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.