Istnieje wiele czynników, które ograniczają wydajność eksportu.
- Rozmiar danych jest stosunkowo duży w porównaniu z dostępną pamięcią:~2 TB vs. ~5 GB pamięci podręcznej WiredTiger (jeśli jest ustawiona domyślnie). Czyli:
- Cała pamięć podręczna WiredTiger może zawierać tylko w najlepszym razie ~0,22% kolekcji, w rzeczywistości jest to prawdopodobnie znacznie mniej, ponieważ pamięć podręczna zawierałaby dane z innych kolekcji i indeksów.
- Oznacza to, że WiredTiger musi bardzo często pobierać dane z dysku, jednocześnie usuwając bieżącą zawartość pamięci podręcznej. Jeśli zestaw replik jest aktywnie używany, oznaczałoby to usunięcie „brudnych” danych z pamięci podręcznej i utrwalenie ich na dysku, co zajęłoby trochę czasu.
- Pamiętaj, że dokumenty w pamięci podręcznej WiredTiger nie są kompresowane.
- Zbiór zawiera duże dokumenty, z których potrzebujesz tylko jednej części. Oznacza to, że potrzebny jest dodatkowy czas na przetworzenie dokumentów.
- Kolekcja jest skompresowana za pomocą zlib, co oznacza, że na dekompresję dokumentów należy poświęcić dodatkowy czas.
- ReadPreference jest
secondaryPreferred
, co oznacza, że będzie próbował czytać z drugorzędnego. Jeśli zestaw replik jest aktywnie zapisywany, operacje zastosowania oplog na serwerze pomocniczym zablokują czytniki. Doda to dalsze opóźnienie.
Jednym z możliwych ulepszeń jest to, że jeśli jest to operacja, którą wykonujesz często, tworzenie indeksu na odpowiednich polach i eksportowanie go za pomocą kryte zapytanie może poprawić wydajność, ponieważ indeks byłby mniejszy niż pełne dokumenty.
Edytuj:uruchamianie mongoexport
równolegle może być pomocne w tym przypadku:
Poza dostarczonymi dodatkowymi informacjami przeprowadziłem test, który wydaje się nieco łagodzić ten problem.
Wygląda na to, że uruchomienie mongoexport
równolegle, gdzie każdy mongoexport
obsługa podzbioru kolekcji może przyspieszyć eksport.
Aby to zrobić, podziel _id
przestrzeń nazw odpowiadająca numerowi mongoexport
proces, który planujesz uruchomić.
Na przykład, jeśli mam 200 000 dokumentów, zaczynając od _id:0
do _id:199,999
i używając 2 mongoexport
procesy:
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 &
gdzie w powyższym przykładzie dwa mongoexport
każdy z procesów obsługuje połowę kolekcji.
Testując ten przepływ pracy z 1 procesem, 2 procesami, 4 procesami i 8 procesami, dochodzę do następujących czasów:
Za pomocą 1 procesu:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 procesy:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 procesy:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 procesów:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
W zależności od dostępnych zasobów, uruchomienie 8 mongoexport
procesy równoległe wydają się przyspieszać ten proces ~6-krotnie. Zostało to przetestowane na maszynie z 8 rdzeniami.
Uwaga :odpowiedź halfera jest podobna, chociaż ta odpowiedź zasadniczo próbuje sprawdzić, czy jest jakaś korzyść z wywołania mongoexport
równolegle.