2012-10-24 12 views
7

Sto riscontrando difficoltà nel memorizzare centinaia di milioni di coppie chiave/valore di 16/32byte con un array hash sul mio SSD.Cabinet Kyoto/Berkeley DB: Limiti di dimensione tabella hash

Con cabinet Kyoto: Quando funziona correttamente, inserisce a 70000 record/s. Una volta che scende, scende a 10-500 record/s. Con le impostazioni predefinite, la caduta avviene dopo circa un milione di record. Guardando la documentazione, questo è il numero predefinito di bucket nell'array, quindi ha senso. Ho aumentato questo numero a 25 milioni e, di fatto, funziona fino a circa 25 milioni di record. Il problema è che, non appena spingo il numero di bucket a 30 milioni o più, la frequenza di inserimento è ridotta a 10-500 record/s dall'inizio. Kyoto Cabinet non è progettato per aumentare il numero di bucket dopo la creazione del database, quindi non posso inserire più di 25 milioni di record.

1/Perché la frequenza di inserimento di KC diventa molto bassa una volta che il numero della benna supera 25 M?

Con Berkeley DB: la velocità migliore che ho avuto è leggermente inferiore rispetto KC, più vicino a 50000 di registrazione/s, ma ancora ok. Con le impostazioni predefinite, proprio come KC, la velocità diminuisce improvvisamente dopo circa un milione di record. So che BDB è progettato per estendere gradualmente il suo numero di secchi. Indipendentemente da ciò, ha cercato di aumentare il numero iniziale, giocando con HashNumElements e FillFactor, ma nessuno di questi tentativi ha peggiorato la situazione. Quindi non riesco ancora a inserire oltre 1-2 milioni di record con DBD. Ho provato ad attivare transazioni non sincronizzate, ho provato diversi tassi di checkpoint, aumentato il numero di cache. Niente migliora la discesa.

2/Cosa potrebbe causare la caduta della frequenza di inserimento di BDB dopo 1-2 milioni di inserti?

Nota: Sto lavorando con Java, e quando la velocità è in calo, l'utilizzo della CPU abbassa al 0-30%, mentre al 100% quando si lavora a velocità corretta.
Nota: Arrestare il processo e riprendere l'inserimento non cambia nulla. Quindi non penso che sia legato ai limiti di memoria o alla garbage collection.

Thx.

+0

Che aspetto ha l'ambiente BDB? stai usando transazioni, repliche, ecc.? Inoltre, puoi pubblicare qualche codice di esempio? –

+0

Lo stato corrente è: [pastebin.com/bWJpbipZ](http://pastebin.com/bWJpbipZ). Inserisco con 'database.put (transaction, k, v)', letto con 'database.get (transazione, k, v, LockMode.DEFAULT)', e checkpoint ogni 500000 inserti con 'environment.checkpoint (null)'. –

risposta

3

Di seguito è come sono riuscito a memorizzare miliardi di record nonostante le limitazioni di scrittura riscontrate con KC.

Con molto sforzo, non ho ancora risolto il problema né per Kyoto Cabinet né per Berkeley DB. Tuttavia, ho trovato una soluzione interessante con il Cabinet di Kyoto.

Ho notato che non riesco a scrivere più di 25 milioni di record su un solo file KC, ma read non ha tale limite - è sempre veloce, indipendentemente dalle dimensioni del database. La soluzione che ho trovato è creare un nuovo file KC (un nuovo database) per ogni 25 milioni di nuovi record. In questo modo la lettura avviene su molti file KC ed è ancora veloce, e la scrittura avviene solo sull'ultimo file creato ed è anche veloce. L'unico problema rimanente era consentire l'aggiornamento/eliminazione dei record sui file precedenti. Per questo, ho copiato i SSTables avvicinano, che è:

  • Tutte le 0 a N-1 file sono di sola lettura, il file viene letto N + scrivere.
  • Qualsiasi inserimento/aggiornamento/cancellazione è scritto nel file N.
  • Le letture esaminano i file da N a 0 e restituiscono l'inserimento/l'aggiornamento/l'eliminazione prima vista/ultima scritta.
  • Un filtro di fioritura è collegato a ciascun file per evitare l'accesso a un file che non ha il record desiderato.
  • Non appena il file N raggiunge i record 25M, diventa di sola lettura e viene creato il file N + 1.

Note:

  • Proprio come con SSTables, se un sacco di aggiornamenti/eliminazioni vengono eseguite, si potrebbe desiderare di eseguire la compattazione. Tuttavia, contrariamente a SSTables, la compattazione non richiede di riscrivere il file. I record obsoleti vengono semplicemente rimossi dai file KC e, se un file KC diventa molto piccolo, può essere rimosso rimuovendo i record nel file N- o riaperto per i nuovi inserimenti, in quanto i file successivi sono compatti.
  • Una cancellazione non cancella il record, ma scrive un valore speciale che identifica il record come cancellato. Durante la compattazione, i record cancellati vengono rimossi per davvero.
  • Controllare se esiste un record in genere richiede di esaminare il database. Grazie ai filtri di fioritura, la maggior parte delle risposte negative possono essere fornite senza alcun accesso al disco.