2013-02-25 2 views
2

berkeleydb-JE에 ~ 56,249,000 개의 항목을 삽입하려고합니다. 내 데이터베이스에 대한 몇 가지 통계를 얻을 수 에게는 dbcachesize을 실행 : 나는 2 년 전 Optimizing a BerkeleyDB JE Database이 질문을하지만 난 아직도 내가 그 통계에서 내 환경을 구성하는 방법을 잘 모르겠어요 BerkeleyDB-JE에 데이터를 삽입하는 속도가 느려지고 느려짐

java -jar je-5.0.34.jar DbCacheSize -records 56248699 -key 8 -data 20 

=== Environment Cache Overhead === 

3,155,957 minimum bytes 

To account for JE daemon operation and record locks, 
a significantly larger amount is needed in practice. 

=== Database Cache Size === 

Minimum Bytes Maximum Bytes Description 
--------------- --------------- ----------- 
    1,287,110,736 1,614,375,504 Internal nodes only 
    4,330,861,264 4,658,126,032 Internal nodes and leaf nodes 

=== Internal Node Usage by Btree Level === 

Minimum Bytes Maximum Bytes  Nodes Level 
--------------- --------------- ---------- ----- 
    1,269,072,064 1,592,660,160  632,008 1 
    17,837,712  21,473,424  7,101 2 
     198,448   238,896   79 3 
      2,512   3,024   1 4 

?

데이터를로드 할 때 나는 데이터베이스에 액세스 할 수있는 유일한 사용자가됩니다. 트랜잭션을 사용해야합니까?

내 ENV는 현재 다음과 같이 열립니다 :

EnvironmentConfig cfg=(...) 
cfg.setTransactional(true); 
cfg.setAllowCreate(true); 
cfg.setReadOnly(false); 
cfg.setCachePercent(80); 
cfg.setConfigParam(EnvironmentConfig.LOG_FILE_MAX,"250000000"); 

데이터베이스 :

cfg.setAllowCreate(true); 
cfg.setTransactional(true); 
cfg.setReadOnly(false); 

내가 항목을 다음과 같은 방법을 삽입/읽기 :

Transaction txn= env.beginTransaction(null, null); 
//open db with transaction 'txn' 
Database db=env.open(...txn) 

Transaction txn2=this.getEnvironment().beginTransaction(null, null); 
long record_id=0L; 
while((item=readNextItem(input))!=null) 
    { 
    (...) 
    ++record_id; 

    db.put(...); //insert record_id/item into db 
    /** every 100000 items commit and create a new transaction. 
     I found it was the only way to avoid an outOfMemory exception */ 
    if(record_id%100000==0) 
     { 
     txn2.commit(); 
     System.gc(); 
     txn2=this.getEnvironment().beginTransaction(null, null); 
     } 
    } 

txn2.commit(); 
txn.commit(); 

하지만 상황이 점점 천천히 그리고 천천히. 나는 JVM을 위해 아무것도 설정하지 않고 이클립스에서 프로그램을 돌렸다.

100000/56248699 (0.2 %). 13694.9 records/seconds. Time remaining:68.3 m Disk Usage: 23.4 Mb. Expect Disk Usage: 12.8 Gb Free Memory : 318.5 Mb. 
200000/56248699 (0.4 %). 16680.6 records/seconds. Time remaining:56.0 m Disk Usage: 49.5 Mb. Expect Disk Usage: 13.6 Gb Free Memory : 338.3 Mb. 
(...) 
6600000/56248699 (11.7 %). 9658.2 records/seconds. Time remaining:85.7 m Disk Usage: 2.9 Gb. Expect Disk Usage: 24.6 Gb Free Memory : 165.0 Mb. 
6700000/56248699 (11.9 %). 9474.5 records/seconds. Time remaining:87.2 m Disk Usage: 2.9 Gb. Expect Disk Usage: 24.7 Gb Free Memory : 164.8 Mb. 
6800000/56248699 (12.1 %). 9322.6 records/seconds. Time remaining:88.4 m Disk Usage: 3.0 Gb. Expect Disk Usage: 24.8 Gb Free Memory : 164.8 Mb. 
(Ctrl-C... abort...) 

어떻게하면 더 빠르게 만들 수 있습니까?

업데이트 :

MemTotal:  4021708 kB 
MemFree:   253580 kB 
Buffers:   89360 kB 
Cached:   1389272 kB 
SwapCached:   56 kB 
Active:   2228712 kB 
Inactive:  1449096 kB 
Active(anon): 1793592 kB 
Inactive(anon): 596852 kB 
Active(file):  435120 kB 
Inactive(file): 852244 kB 
Unevictable:   0 kB 
Mlocked:    0 kB 
HighTotal:  3174028 kB 
HighFree:   57412 kB 
LowTotal:   847680 kB 
LowFree:   196168 kB 
SwapTotal:  4085756 kB 
SwapFree:  4068224 kB 
Dirty:    16320 kB 
Writeback:    0 kB 
AnonPages:  2199056 kB 
Mapped:   111280 kB 
Shmem:   191272 kB 
Slab:    58664 kB 
SReclaimable:  41448 kB 
SUnreclaim:  17216 kB 
KernelStack:  3792 kB 
PageTables:  11328 kB 
NFS_Unstable:   0 kB 
Bounce:    0 kB 
WritebackTmp:   0 kB 
CommitLimit:  6096608 kB 
Committed_AS: 5069728 kB 
VmallocTotal:  122880 kB 
VmallocUsed:  18476 kB 
VmallocChunk:  81572 kB 
HardwareCorrupted:  0 kB 
AnonHugePages:   0 kB 
HugePages_Total:  0 
HugePages_Free:  0 
HugePages_Rsvd:  0 
HugePages_Surp:  0 
Hugepagesize:  2048 kB 
DirectMap4k:  10232 kB 
DirectMap2M:  903168 kB 

업데이트 2 :

Max. Heap Size (Estimated): 872.94M 
Ergonomics Machine Class: server 
Using VM: Java HotSpot(TM) Server VM 

갱신 3 : Jerven의 조언을 사용

, 나는 다음과 같은 성능을 얻을 :

(...) 
    6800000/56248699 (12.1 %). 13144.8 records/seconds. Time remaining:62.7 m Disk Usage: 1.8 Gb. Expect Disk Usage: 14.6 Gb Free Memory : 95.5 Mb. 
    (...) 

내 이전 대를 결과 :

6800000/56248699 (12.1 %). 9322.6 records/seconds. Time remaining:88.4 m Disk Usage: 3.0 Gb. Expect Disk Usage: 24.8 Gb Free Memory : 164.8 Mb. 
+0

JVM 및 기계 세부 사항을 추가 할 수 있습니까? – Jerven

+0

Java (TM) SE Runtime Environment (빌드 1.7.0_07-b10) – Pierre

+0

Linux 이름 3.2.0-38-generic-pae # 60-Ubuntu SMP Wed 2 월 13 일 13:47:26 UTC 2013 i686 i686 i386 GNU/Linux – Pierre

답변

2

먼저 System.gc()에 대한 명시 적 호출을 제거합니다. 이 보조 기능 성능이 다른 GC 알고리즘으로 이동하는 것을 확인한 경우 예를 들어, bdb/je 캐시 사용이 일관되게 사용 가능한 힙의 70 %에 가까울 때 G1GC가 더 잘 수행됩니다.

두 번째로 B + 인덱스 업데이트는 nlog n 성능이되고 삽입 시간이 줄어 듭니다.

트랜잭션을 사용하지 않는 것이 빠릅니다. 특히 실패 할 경우 가져 오기를 처음부터 다시 시작할 수 있는지 여부.

환경의 .sync() 및 끝에 체크 포인트를 수행하는 것을 잊지 마십시오. 이 가져 오기를 수행하는 동안 BDB/je 검사 점 및 BDB/je GC 스레드를 비활성화 할 수 있습니다.

config.setConfigParam(EnvironmentConfig.ENV_RUN_CLEANER, "false"); 
config.setConfigParam(EnvironmentConfig.ENV_RUN_CHECKPOINTER, "false); 
config.setConfigParam(EnvironmentConfig.ENV_RUN_IN_COMPRESSOR, "false"); 

로드 한 후 다음과 같은 메소드를 호출해야합니다.

public void checkpointAndSync() 
    throws ObjectStoreException 
{ 
      env.sync(); 
    CheckpointConfig force = new CheckpointConfig(); 
    force.setForce(true); 
    try 
    { 
     env.checkpoint(force); 
    } catch (DatabaseException e) 
    { 
     log.error("Can not chekpoint db " + path.getAbsolutePath(), e); 
     throw new ObjectStoreException(e); 
    } 
} 

keyprefixing도 고려할 수 있습니다.

내부 노드 캐시 크기는 1.6GB 이상이어야합니다. 즉, 시작할 때 2GB보다 큰 힙을 의미합니다.

레코드를 병합하는 것도 고려해 볼 수 있습니다. 예를 들어 키가 자연스럽게 증가하는 경우 하나의 키 아래에 16 개의 값을 저장할 수 있습니다. 그러나이 방법을 재미있는 것으로 생각한다면 increasing the B tree fanout setting으로 시작할 수 있습니다.

+0

이것은 내가 받아 들여 투표 할 대답입니다. 잘 했어. – duffymo

관련 문제