De nombreux facteurs limitent les performances à l'exportation.
- La taille des données est relativement importante par rapport à la mémoire disponible :~2 To contre ~5 Go de cache WiredTiger (si défini par défaut). C'est-à-dire :
- L'ensemble du cache WiredTiger ne peut contenir au mieux ~0,22 % de la collection, en réalité c'est très probablement beaucoup moins que cela puisque le cache contiendrait des données d'autres collections et index.
- Cela signifie que WiredTiger doit extraire du disque très fréquemment, tout en supprimant le contenu actuel du cache. Si le jeu de réplicas est activement utilisé, cela impliquerait d'expulser les données "sales" du cache et de les conserver sur le disque, ce qui prendrait du temps.
- Notez que les documents à l'intérieur du cache WiredTiger ne sont pas compressés.
- La collection contient des documents volumineux, dont vous n'avez besoin que d'une partie. Cela signifie qu'un délai supplémentaire est nécessaire pour traiter les documents.
- La collection est compressée avec zlib, ce qui signifie que du temps supplémentaire doit être utilisé pour décompresser les documents.
- Le readPreference est
secondaryPreferred
, ce qui signifie qu'il essaiera de lire à partir d'un fichier secondaire. Si le jeu de réplicas est en cours d'écriture active, les opérations d'application oplog sur le secondaire bloqueront les lecteurs. Cela ajoutera un délai supplémentaire.
Une amélioration possible est que s'il s'agit d'une opération que vous faites fréquemment, créer un index sur les champs pertinents et l'exporter à l'aide d'un requête couverte pourrait améliorer les performances puisque l'index serait plus petit que les documents complets.
Modifier :Exécuter mongoexport
en parallèle peut être utile dans ce cas :
En plus des informations supplémentaires fournies, j'ai effectué un test qui semble atténuer quelque peu ce problème.
Il semble que l'exécution de mongoexport
en parallèle, où chaque mongoexport
la gestion d'un sous-ensemble de la collection peut accélérer l'exportation.
Pour cela, divisez le _id
espace de noms correspondant au nombre de mongoexport
processus que vous prévoyez d'exécuter.
Par exemple, si j'ai 200 000 documents, commençant par _id:0
à _id:199,999
et en utilisant 2 mongoexport
processus :
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 &
où dans l'exemple ci-dessus, les deux mongoexport
les processus traitent chacun la moitié de la collection.
En testant ce flux de travail avec 1 processus, 2 processus, 4 processus et 8 processus, j'arrive aux horaires suivants :
En utilisant 1 processus :
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 processus :
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 processus :
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 processus :
real 0m5.069s
user 0m4.520s
sys 0m0.364s
Selon les ressources disponibles, lancer 8 mongoexport
processus en parallèle semble accélérer le processus d'un facteur ~6. Cela a été testé sur une machine à 8 cœurs.
Remarque :la réponse de halfer est similaire dans l'idée, bien que cette réponse essaie essentiellement de voir s'il y a un avantage à appeler mongoexport
en parallèle.