Има много фактори, които ограничават ефективността на експорта.
- Размерът на данните е относително голям в сравнение с наличната памет:~2 TB срещу ~5 GB WiredTiger кеш (ако е зададен по подразбиране). Това е:
- Целият кеш на WiredTiger може да съдържа само в най-добрия случай ~0,22% от колекцията, в действителност много вероятно е много по-малко от това, тъй като кешът ще съдържа данни от други колекции и индекси.
- Това означава, че WiredTiger трябва да извлича от диска много често, като същевременно изхвърля текущото съдържание на кеша. Ако наборът реплики се използва активно, това би означавало изгонване на „мръсни“ данни от кеша и запазването им на диск, което би отнело време.
- Имайте предвид, че документите в кеша на WiredTiger не са компресирани.
- Колекцията съдържа големи документи, от които ви е необходима само една част. Това означава, че е необходимо допълнително време за обработка на документите.
- Колекцията е компресирана със zlib, което означава, че трябва да се използва допълнително време за декомпресиране на документите.
- Предпочитанието за четене е
secondaryPreferred
, което означава, че ще се опита да чете от вторичен. Ако наборът реплики се записва активно, операциите за прилагане на oplog на вторичния ще блокират четците. Това ще добави допълнително забавяне.
Едно възможно подобрение е, ако това е операция, която извършвате често, създаване на индекс на съответните полета и експортирането му с помощта на покрита заявка може да подобри производителността, тъй като индексът ще бъде по-малък от пълните документи.
Редактиране:Стартиране на mongoexport
паралелно може да бъде полезно в този случай:
Освен предоставената допълнителна информация, проведох тест, който изглежда облекчава донякъде този проблем.
Изглежда, че изпълнява mongoexport
паралелно, където всеки mongoexport
обработката на подмножество от колекцията може да ускори експортирането.
За да направите това, разделете _id
пространство от имена, съответстващо на номера на mongoexport
процес, който планирате да стартирате.
Например, ако имам 200 000 документа, започващи с _id:0
до _id:199,999
и използвайки 2 mongoexport
процеси:
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 &
където в горния пример двата mongoexport
всеки процес обработва половината от колекцията.
Тествайки този работен процес с 1 процес, 2 процеса, 4 процеса и 8 процеса, стигнах до следните времена:
Използване на 1 процес:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 процеса:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 процеса:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 процеса:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
В зависимост от наличните ресурси, стартиране на 8 mongoexport
паралелните процеси изглежда ускоряват процеса с коефициент ~6. Това беше тествано в машина с 8 ядра.
Забележка :отговорът на halfer е подобен по идея, въпреки че този отговор основно се опитва да види дали има някаква полза от извикването на mongoexport
паралелно.