데이터를 디스크로 유지하고 무작위로 업데이트하고 RAM으로 효율적으로 스트리밍하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1274562

문제

나는 수십만 또는 수억 조각의 데이터 온 디스크를 저장해야합니다. 각 데이터 조각에는 다음과 같은 정보가 포함됩니다.

id=23425
browser=firefox
ip-address=10.1.1.1
outcome=1.0

새로운 데이터 조각은 밀리 초당 최대 1의 속도로 추가 될 수 있습니다.

따라서 값이 문자열, 정수 또는 부유물 일 수있는 비교적 간단한 키 값 쌍 세트입니다. 때때로 특정 ID로 데이터 조각을 업데이트하고 플래그 필드를 0에서 1으로 변경해야 할 수도 있습니다. 즉, ID로 임의의 키 조회를 수행하고 데이터를 수정할 수 있어야합니다 (실제로 플로팅 만 수정해야합니다. 포인트 "결과"필드 - 값의 크기를 수정할 필요가 없습니다).

다른 요구 사항은이 데이터를 디스크 (주문이 특히 중요하지 않음)에서 효율적으로 스트리밍 할 수 있어야한다는 것입니다. 즉, 하드 디스크 헤드가 데이터를 읽기 위해 디스크 주위를 점프 할 필요가 없으며 연속 디스크 블록으로 읽어야합니다.

나는 이것을 Java로 쓰고 있습니다.

임베디드 데이터베이스를 사용하는 것에 대해 생각했지만 DB4O는 GPL이므로 내 코드의 나머지 부분이 아니기 때문에 옵션이 아닙니다. 또한 SQL 쿼리를 오가는 오버 헤드를 고려할 때 임베디드 SQL 데이터베이스를 사용하는 효율성에 대해서도 걱정됩니다.

아무도 아이디어가 있습니까? 이것에 대한 사용자 정의 솔루션을 구축해야 할 수도 있습니다 (바이트 버퍼를 직접 처리하고 ID 조회 처리를 처리하는 곳)?

도움이 되었습니까?

해결책 7

결국 나는 데이터를 디스크에 로그인하고 업데이트 할 수있는 곳에 메모리를 유지하기로 결정했습니다. 일정 기간이 지나면 데이터를 디스크에 쓰고 로그를 삭제합니다.

다른 팁

어때 H2? 그만큼 특허 당신을 위해 일해야합니다.

  • H2를 무료로 사용할 수 있습니다. 응용 프로그램에 통합 할 수 있으며 (상용 응용 프로그램 포함) 배포 할 수 있습니다.
  • 코드 만 포함 된 파일은이 라이센스에 포함되지 않습니다 ( '상업적 친화적').
  • H2 소스 코드에 대한 수정을 게시해야합니다.
  • 아무것도 수정하지 않은 경우 H2의 소스 코드를 제공 할 필요가 없습니다.

나는 얻다

22492ms (44460.252534234394 행/초)의 10000000 삽입물

9565ms (10454.783063251438 Row/Sec)의 10000 개 업데이트

~에서

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;


/**
 * @author clint
 *
 */
public class H2Test {

  static int testrounds = 1000000;

  public static void main(String[] args) {
    try {
      Class.forName("org.h2.Driver");

    Connection conn = DriverManager.
        getConnection("jdbc:h2:/tmp/test.h2", "sa", "");
    // add application code here
    conn.createStatement().execute("DROP TABLE IF EXISTS TEST");
    conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TEST(id INT PRIMARY KEY, browser VARCHAR(64),ip varchar(16), outcome real)"); 
    //conn.createStatement().execute("CREATE INDEX IDXall ON TEST(id,browser,ip,outcome");


    PreparedStatement ps = conn.prepareStatement("insert into TEST (id, browser, ip, outcome) values (?,?,?,?)");
    long time = System.currentTimeMillis();
    for ( int i = 0; i < testrounds; i++ ) {
      ps.setInt(1,i);
      ps.setString(2,"firefox");
      ps.setString(3,"000.000.000.000");
      ps.setFloat(4,0);
      ps.execute();
    }
    long last = System.currentTimeMillis() ;
    System.out.println( testrounds + " insert in " + (last - time) + "ms (" + ((testrounds)/((last - time)/1000d)) + " row/sec)" );

    ps.close();
    ps = conn.prepareStatement("update TEST set outcome = 1 where id=?");
    Random random = new Random();
    time = System.currentTimeMillis();

    /// randomly updadte 10% of the entries
    for ( int i = 0; i < testrounds/10; i++ ) {
      ps.setInt(1,random.nextInt(testrounds));
      ps.execute();
    }

    last = System.currentTimeMillis();
    System.out.println( (testrounds/10) + " updates in " + (last - time) + "ms (" + ((testrounds/10)/((last - time)/1000d)) + " row/sec)" );

    conn.close();

    } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

}

JDBM Java를위한 훌륭한 임베디드 데이터베이스입니다 (Berkley의 Java 버전만큼 라이센스가 포함되어 있지 않음). 시도해 볼 가치가 있습니다. 산성 보증이 필요하지 않은 경우 (즉, 충돌시 데이터베이스가 손상되어 괜찮습니다) 트랜잭션 관리자를 끄십시오 (속도가 크게 증가).

메모리에서 가장 활발한 레코드를 캐시하고 DB에 우선 순위가 낮은 삽입으로 데이터 변경을 대기하는 것을 쓰는 것이 훨씬 더 성공적이라고 생각합니다.

이 방법을 사용하여 IO가 약간 증가한 것으로 이해하지만 수백만의 레코드에 대해 이야기하고 있다면 AA Full Sledged Database Engine에 의해 생성 된 검색 알고리즘이 크게 성능이 우수하기 때문에 여전히 더 빠를 것이라고 생각합니다.

당신은 시도 할 수 있습니다 버클리 DB 현재 Oracle이 소유하고 있습니다. 그들은 오픈 소스 및 상업 라이센스를 가지고 있습니다. 키/값 모델을 사용합니다 (다른 형식의 쿼리가 필요한 경우 인덱스를 생성하는 옵션이 포함되어 있음). 순수한 Java 버전과 Java 바인딩이있는 기본 버전이 있습니다.

http://www.zentus.com/sqlitejdbc/

SQLITE 데이터베이스 (공개 도메인), BSD 라이센스가있는 JDBC 커넥터, 전체 플랫폼 (OSX, Linux, Windows), 나머지에 대한 에뮬레이션.

JDK와 함께 번들로 제공되는 Apache Derby (또는 Javadb)를 사용할 수 있습니다. 그러나 DBMS가 필요한 속도를 제공하지 않으면 특정 파일 구조를 직접 구현할 수 있습니다. 정확한 키 조회가 필요한 경우 해시 파일을 사용하여 구현할 수 있습니다. 해시 파일은 이러한 요구 사항에 대한 가장 빠른 파일 구조입니다 (DBS에서 사용되는 B- 트리 및 그리드와 같은 범용 파일 구조보다 훨씬 빠릅니다). 또한 허용 가능한 스트리밍 효율을 제공합니다.

Oracle의 'Timesten'데이터베이스를 살펴 보셨습니까? 그것은 매우 높은 성능으로 여겨지는 메모리 DB입니다. 비용/라이센스 등에 대해 알지 못하지만 Oracles 사이트를 살펴보고 검색하십시오. 평가 다운로드를 사용할 수 있어야합니다.

또한 ehcache 또는 JC를 기반으로 기존의 것이 있는지 살펴 보겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top