Det finns många faktorer som begränsar exportresultatet.
- Datastorleken är relativt stor jämfört med tillgängligt minne:~2 TB vs. ~5 GB WiredTiger-cache (om inställt på standard). Det vill säga:
- Hela WiredTiger-cachen kan bara innehålla i bästa fall ~0,22 % av samlingen, i verkligheten är det mycket troligt mycket mindre än detta eftersom cachen skulle innehålla data från andra samlingar och index.
- Detta betyder att WiredTiger måste hämta från disken mycket ofta, samtidigt som det aktuella innehållet i cachen rensas. Om replikuppsättningen används aktivt skulle det innebära att "smutsiga" data kastas bort från cacheminnet och lagras på disken, vilket skulle ta tid.
- Observera att dokument i WiredTiger-cachen inte komprimeras.
- Samlingen innehåller stora dokument, av vilka du bara behöver en del av den. Det innebär att det krävs extra tid för att behandla handlingarna.
- Samlingen är komprimerad med zlib, vilket innebär att extra tid måste användas för att packa upp dokumenten.
- Läspreferensen är
secondaryPreferred
, vilket betyder att den kommer att försöka läsa från en sekundär. Om replikuppsättningen aktivt skrivs till, kommer oplog-appliceringsoperationer på den sekundära att blockera läsare. Detta kommer att lägga till ytterligare förseningar.
En möjlig förbättring är att om detta är en operation som du gör ofta, skapa ett index på de relevanta fälten och exportera det med en täckt fråga kan förbättra prestandan eftersom indexet skulle vara mindre än de fullständiga dokumenten.
Redigera:Kör mongoexport
parallellt kan vara till hjälp i det här fallet:
Utöver den ytterligare informationen som tillhandahålls körde jag ett test som verkar lindra problemet något.
Det verkar som att köra mongoexport
parallellt, där varje mongoexport
hantering av en delmängd av samlingen kan påskynda exporten.
För att göra detta, dela _id
namnutrymme som motsvarar antalet mongoexport
process du planerar att köra.
Till exempel, om jag har 200 000 dokument, börjar med _id:0
till _id:199,999
och använder 2 mongoexport
processer:
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 &
där i exemplet ovan, de två mongoexport
processer hanterar var och en hälften av insamlingen.
När jag testar detta arbetsflöde med 1 process, 2 processer, 4 processer och 8 processer kommer jag fram till följande tidpunkter:
Använder en process:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 processer:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 processer:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 processer:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
Beroende på tillgängliga resurser, kör 8 mongoexport
parallella processer verkar påskynda processen med en faktor på ~6. Detta testades i en maskin med 8 kärnor.
Obs :halfers svar liknar idén, även om det här svaret i princip försöker se om det finns någon fördel med att ringa mongoexport
parallellt.