Er zijn veel factoren die de exportprestaties beperken.
- De gegevensgrootte is relatief groot in vergelijking met het beschikbare geheugen:~2 TB versus ~5 GB WiredTiger-cache (indien ingesteld op standaard). Dat is:
- De hele WiredTiger-cache kan slechts op zijn best . bevatten ~0,22% van de verzameling, in werkelijkheid is het zeer waarschijnlijk veel minder dan dit, aangezien de cache gegevens uit andere verzamelingen en indexen zou bevatten.
- Dit betekent dat WiredTiger heel vaak van schijf moet ophalen, terwijl de huidige inhoud van de cache wordt verwijderd. Als de replicaset actief wordt gebruikt, zou dit betekenen dat "vuile" gegevens uit de cache moeten worden verwijderd en op schijf moeten worden bewaard, wat tijd zou kosten.
- Houd er rekening mee dat documenten in de WiredTiger-cache niet worden gecomprimeerd.
- De collectie bevat grote documenten, waarvan je maar een deel nodig hebt. Dit betekent dat er extra tijd nodig is om de documenten te verwerken.
- De verzameling is gecomprimeerd met zlib, wat betekent dat er extra tijd moet worden besteed aan het decomprimeren van de documenten.
- De leesvoorkeur is
secondaryPreferred
, wat betekent dat het zal proberen te lezen van een secundair. Als er actief naar de replicaset wordt geschreven, zullen oplog-toepassingsbewerkingen op de secundaire lezers blokkeren. Dit zorgt voor verdere vertraging.
Een mogelijke verbetering is dat als dit een bewerking is die u vaak uitvoert, een index op de relevante velden wordt gemaakt en deze wordt geëxporteerd met behulp van een overdekte zoekopdracht zou de prestaties kunnen verbeteren, aangezien de index kleiner zou zijn dan de volledige documenten.
Bewerken:mongoexport
uitvoeren parallel kan in dit geval nuttig zijn:
Op basis van de aanvullende informatie die werd verstrekt, heb ik een test uitgevoerd die dit probleem enigszins lijkt te verlichten.
Het lijkt erop dat het uitvoeren van mongoexport
parallel, waarbij elke mongoexport
het verwerken van een subset van de verzameling kan de export mogelijk versnellen.
Om dit te doen, deelt u de _id
naamruimte die overeenkomt met het nummer van mongoexport
proces dat u wilt uitvoeren.
Als ik bijvoorbeeld 200.000 documenten heb, beginnend met _id:0
naar _id:199,999
en gebruik 2 mongoexport
processen:
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 &
waarbij in het bovenstaande voorbeeld de twee mongoexport
processen nemen elk de helft van de collectie voor hun rekening.
Bij het testen van deze workflow met 1 proces, 2 processen, 4 processen en 8 processen kom ik op de volgende tijdstippen:
1 proces gebruiken:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 processen:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 processen:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 processen:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
Afhankelijk van de beschikbare bronnen, draait u 8 mongoexport
parallelle processen lijkt het proces met een factor ~6 te versnellen. Dit is getest in een machine met 8 cores.
Opmerking :het antwoord van halfer is vergelijkbaar in idee, hoewel dit antwoord in feite probeert te zien of het enig voordeel heeft om mongoexport
te bellen parallel.