2012-06-17 17 views
9

Sto memorizzando un grande array binario all'interno di un documento. Desidero aggiungere continuamente byte a questo array e talvolta modificare il valore dei byte esistenti.Come archiviare e aggiornare in modo efficiente i dati binari in Mongodb?

Stavo cercando alcuni tipi di modificatori $ append_bytes e $ replace_bytes ma sembra che il meglio che posso fare sia $ push per gli array. Sembra che sarebbe fattibile eseguendo operazioni di tipo seek-write se avessi accesso in qualche modo al bson sottostante su disco, ma non mi sembra che ci sia comunque da fare in mongodb (e probabilmente per una buona ragione).

Se dovessi interrogare questo array binario, modificarlo o aggiungerlo e quindi aggiornare il documento riscrivendo l'intero campo, quanto sarà costoso? Ogni array binario sarà dell'ordine di 1-2 MB e gli aggiornamenti si verificano ogni 5 minuti e su 1000 di documenti. Peggio ancora, ma non esiste un modo semplice per distribuirli (in tempo) e di solito accadranno vicini l'un l'altro agli intervalli di 5 minuti. Qualcuno ha una buona sensazione di quanto sarà disastroso? Sembra che sarebbe problematico.

Un'alternativa sarebbe quella di memorizzare questi dati binari come file separati su disco, implementare un pool di thread per manipolare in modo efficiente i file su disco e fare riferimento al nome file dal mio documento mongodb. (Sto usando python e pymongo quindi stavo guardando a pytables). Preferirei evitare questo, se possibile.

C'è qualche altra alternativa che sto trascurando qui?

Grazie in anticipo.

EDIT

Dopo alcuni lavori di scrittura di alcuni test per i miei casi di utilizzo ho deciso di utilizzare un filesystem separato per gli oggetti di dati binari (HDF5 specificamente utilizzando sia pytables o h5py). Userò comunque mongo per tutto tranne la persistenza di questi oggetti dati binari. In questo modo posso disaccoppiare le prestazioni relative ad aggiungere e aggiornare le operazioni di tipo lontano dalla mia performance base di mongo.

Uno degli sviluppatori di mongo ha fatto notare che è possibile impostare gli elementi di array interni utilizzando la notazione di punti e $ set (vedere ref in commento sotto), ma in questo momento non è possibile eseguire un intervallo di set in un array atomicamente.

Inoltre, se ho 1000 di campi di dati binari 2 MB all'interno dei miei documenti mongo e li sto aggiornando e crescendo spesso (come almeno una volta ogni 5 minuti), il mio istinto mi dice che mongo dovrà gestire un sacco di problemi di allocazione/crescita all'interno dei suoi file su disco - e questo alla fine porterà a problemi di prestazioni. Preferirei scaricarlo su un file system separato a livello di sistema operativo da gestire.

Infine, eseguirò la manipolazione e l'esecuzione dei calcoli sui miei dati utilizzando numpy: sia i pytables che i moduli h5py consentono una buona integrazione tra il comportamento numpy e lo store.

+0

E 'stato appena portato alla mia attenzione da uno degli sviluppatori MongoDB cui è possibile accedere elementi di matrice individuali utilizzando $ set con la notazione punto. Ho trascurato questo. Il riferimento è all'indirizzo: http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29#DotNotation%28ReachingintoObjects%29-ArrayElementbyPosition – Rocketman

risposta

4

Come hai già detto, stai modificando frequentemente i dati binari, di fatto molto spesso. GridFS è un'altra opzione che suggerirei.

When to use GridFS potrebbe essere utile a voi

+1

Ho esaminato GridFS ...i file vengono messi() nella raccolta e si occupa della distribuzione automatica in blocchi. È anche emerso che se ho bisogno di cambiare qualcosa - ho quindi bisogno di mettere() di nuovo - che salva un altro intero set di blocchi. Sembra costruito per il controllo delle versioni dei file che non cambiano frequentemente. Quindi nel mio caso avrei un numero enorme di copie del file. A meno che non memorizzi in qualche modo i cambiamenti in qualche modo - ma nessuno della documentazione che ho visto suggerito così ... – Rocketman

+0

Sì, in realtà l'aggiornamento dei mandrini esistenti sarebbe un mal di testa insopportabile. Invece, generalmente si desidera seguire questo schema: 1.) trova quello vecchio, mantieni il _id 2.) aggiungi uno nuovo 3.) rimuovi uno vecchio da _id –

+0

http://stackoverflow.com/questions/6280186/append-data-to-existing-gridfs-file, dai un'occhiata a questo –

Problemi correlati