MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

È possibile migliorare la velocità di Mongoexport?

Ci sono molti fattori che stanno limitando la performance delle esportazioni.

  • La dimensione dei dati è relativamente grande rispetto alla memoria disponibile:~2 TB contro ~5 GB di cache WiredTiger (se impostata come predefinita). Cioè:
    • L'intera cache di WiredTiger può contenere solo al massimo ~0,22% della raccolta, in realtà è molto probabilmente molto inferiore poiché la cache conterrebbe dati da altre raccolte e indici.
    • Ciò significa che WiredTiger deve recuperare molto frequentemente dal disco, rimuovendo il contenuto corrente della cache. Se il set di repliche viene utilizzato attivamente, ciò significherebbe rimuovere i dati "sporchi" dalla cache e mantenerli sul disco, operazione che richiederebbe tempo.
    • Nota che i documenti all'interno della cache di WiredTiger non sono compressi.
  • La collezione contiene documenti di grandi dimensioni, di cui è necessaria solo una parte. Ciò significa che è necessario più tempo per elaborare i documenti.
  • La raccolta è compressa con zlib, il che significa che è necessario utilizzare più tempo per decomprimere i documenti.
  • La readPreference è secondaryPreferred , il che significa che proverà a leggere da un secondario. Se il set di repliche viene scritto attivamente, le operazioni di applicazione di oplog sul secondario bloccheranno i lettori. Ciò aggiungerà ulteriore ritardo.

Un possibile miglioramento è che se si tratta di un'operazione che si esegue frequentemente, creare un indice sui campi rilevanti ed esportarlo utilizzando un query coperta potrebbe migliorare le prestazioni poiché l'indice sarebbe più piccolo dei documenti completi.

Modifica:in esecuzione mongoexport in parallelo può essere utile in questo caso:

Oltre alle informazioni aggiuntive fornite, ho eseguito un test che sembra alleviare in qualche modo questo problema.

Sembra che l'esecuzione di mongoexport in parallelo, dove ogni mongoexport la gestione di un sottoinsieme della raccolta potrebbe velocizzare l'esportazione.

Per fare ciò, dividi il _id namespace corrispondente al numero di mongoexport processo che prevedi di eseguire.

Ad esempio, se ho 200.000 documenti, che iniziano con _id:0 a _id:199,999 e usando 2 mongoexport processi:

mongoexport -q '{"_id":{"$gte":0, "$lt":100000}}' -d test -c test > out1.json &
mongoexport -q '{"_id":{"$gte":100000, "$lt":200000}}' -d test -c test > out2.json &

dove nell'esempio sopra, i due mongoexport i processi gestiscono ciascuno metà della raccolta.

Testando questo flusso di lavoro con 1 processo, 2 processi, 4 processi e 8 processi, arrivo alle seguenti tempistiche:

Utilizzando 1 processo:

real    0m32.720s
user    0m33.900s
sys 0m0.540s

2 processi:

real    0m16.528s
user    0m17.068s
sys 0m0.300s

4 processi:

real    0m8.441s
user    0m8.644s
sys 0m0.140s

8 processi:

real    0m5.069s
user    0m4.520s
sys 0m0.364s

A seconda delle risorse disponibili, eseguendo 8 mongoexport processi in parallelo sembra accelerare il processo di un fattore di ~6. Questo è stato testato su una macchina con 8 core.

Nota :la risposta di halfer è simile nell'idea, sebbene questa risposta fondamentalmente cerchi di vedere se c'è qualche vantaggio nel chiamare mongoexport in parallelo.