Zaobserwowany problem z wydajnością w początkowym zapytaniu jest prawdopodobnie jednym z następujących problemów (w przybliżonej kolejności prawdopodobieństwa):
1) Twoja aplikacja / usługa sieciowa ma pewne obciążenie do zainicjowania przy pierwszym żądaniu (np. przydzielanie pamięci, konfigurowanie pul połączeń, rozwiązywanie DNS, ...).
2) Żądane indeksy lub dane nie znajdują się jeszcze w pamięci, więc należy je załadować.
3) Optymalizator zapytań uruchomienie przy pierwszym żądaniu może potrwać nieco dłużej, ponieważ jest to porównywanie wykonania planu dla wzorca zapytania.
Bardzo pomocne byłoby przetestowanie zapytania za pomocą mongo
powłoki i izoluj, czy obciążenie jest związane z MongoDB, czy z twoją usługą sieciową (zamiast taktowania obu, jak to zrobiłeś).
Poniżej znajduje się kilka uwag związanych z MongoDB.
Buforowanie
MongoDB nie ma czasu „buforowania” dokumentów w pamięci. Wykorzystuje pliki mapowane w pamięci dla operacji we/wy dysku, a dokumenty w pamięci są oparte na aktywnych zapytaniach (dokumenty/indeksy, które ostatnio załadowałeś), a także na dostępnej pamięci. Menedżer pamięci wirtualnej systemu operacyjnego odpowiada za buforowanie , i zazwyczaj postępuje zgodnie z algorytmem LRU (Last-Recently Used) w celu decydowania, które strony zamienić z pamięci.
Wykorzystanie pamięci
Oczekiwane zachowanie jest takie, że z czasem MongoDB będzie się rozrastać i wykorzystywać całą wolną pamięć do przechowywania aktywnego zestawu danych roboczych.
Patrząc na dostarczone db.stats()
liczb (i zakładając, że jest to tylko bazy danych), wygląda na to, że rozmiar Twojej bazy danych wynosi obecnie około 1 GB, więc powinieneś być w stanie zachować wszystko w całkowitej pamięci RAM 10 GB, chyba że:
- Są inne procesy konkurujące o pamięć
- zrestartowałeś swojego
mongod
serwer i te dokumenty/indeksy nie zostały jeszcze zażądane
W MongoDB 2.2 pojawił się nowy touch
polecenie, którego można użyć do załadowania indeksów lub dokumentów do pamięci po ponownym uruchomieniu serwera. Powinno to być używane tylko przy pierwszym uruchomieniu, aby "rozgrzać" serwer, ponieważ w przeciwnym razie możesz nieprzydatnie wymusić rzeczywiste "aktywne" dane z pamięci.
Na przykład w systemie Linux możesz użyć top
polecenie i powinien zobaczyć, że:
- wirtualne bajty/VSIZE będą zwykle odpowiadać rozmiarowi całej bazy danych
- jeśli serwer nie ma uruchomionych innych procesów, rezydentne bajty/RSIZE będą stanowić całkowitą pamięć maszyny (obejmuje to zawartość pamięci podręcznej systemu plików)
mongod
nie powinien używać wymiany (ponieważ pliki są mapowane w pamięci)
Możesz użyć mongostat
narzędzie do szybkiego podglądu swojego mongod
aktywność .. lub bardziej użyteczna, skorzystaj z usługi takiej jak MMS
do monitorowania wskaźników w czasie.
Optymalizator zapytań
MongoDB Optymalizator zapytań
porównuje wykonanie planu dla wzorca zapytania co ~1000 operacji zapisu, a następnie buforuje „wygrywający” plan zapytania do następnego uruchomienia optymalizatora .. lub jawnego wywołania explain()
na to zapytanie.
To powinno być proste do przetestowania:uruchom zapytanie w mongo
powłoka z .explain()
i spójrz na czasy ms, a także liczbę wpisów indeksu i zeskanowanych dokumentów. Czas dla explain() nie jest rzeczywistym czasem uruchomienia zapytań, ponieważ obejmuje on koszt porównania planów. Typowe wykonanie będzie znacznie szybsze ... i możesz szukać wolnych zapytań w swoim mongod
dziennika.
Domyślnie MongoDB rejestruje wszystkie zapytania wolniej niż 100 ms, więc jest to dobry punkt wyjścia do szukania zapytań do optymalizacji. Możesz dostosować powolną wartość ms za pomocą --slowms
opcji konfiguracji lub przy użyciu Database Profiler
poleceń.
Dalsza lektura w dokumentacji MongoDB:
- Buforowanie
- Sprawdzanie użycia pamięci serwera
- Profil bazy danych
- Wyjaśnij
- Monitorowanie i diagnostyka