MongoDB kończy się, gdy zabraknie pamięci

11

Mam następującą konfigurację:

  • maszyna hosta, która obsługuje trzy kontenery dokerów:
    • MongoDB
    • Redis
    • Program wykorzystujący dwa poprzednie kontenery do przechowywania danych

Zarówno Redis, jak i MongoDB służą do przechowywania ogromnych ilości danych. Wiem, że Redis musi przechowywać wszystkie swoje dane w pamięci RAM i nie mam nic przeciwko. Niestety zdarza się, że mongo zaczyna zajmować dużo pamięci RAM, a gdy pamięć RAM hosta jest pełna (mówimy tutaj o 32 GB), następuje awaria mongo lub Redis.

Przeczytałem następujące poprzednie pytania na ten temat:

  1. Ogranicz użycie pamięci RAM MongoDB : najwyraźniej większość pamięci RAM jest zużywana przez pamięć podręczną WiredTiger
  2. Limit pamięci MongoDB : tutaj najwyraźniej problemem były dane dziennika
  3. Ogranicz użycie pamięci RAM w MongoDB : tutaj sugerują ograniczenie pamięci Mongo, aby używała mniejszej ilości pamięci na pamięć podręczną / dzienniki / dane
  4. MongoDB zużywa zbyt dużo pamięci : tutaj mówią, że jest to system buforowania WiredTiger, który zwykle wykorzystuje jak najwięcej pamięci RAM, aby zapewnić szybszy dostęp. Podają takżeit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Czy jest jakaś opcja ograniczenia wykorzystania pamięci Mongodb? : buforowanie ponownie, oni także dodająMongoDB uses the LRU (Least Recently Used) cache algorithm to determine which "pages" to release, you will find some more information in these two questions
  6. Relacja indeks / pamięć RAM MongoDB : cytat:MongoDB keeps what it can of the indexes in RAM. They'll be swaped out on an LRU basis. You'll often see documentation that suggests you should keep your "working set" in memory: if the portions of index you're actually accessing fit in memory, you'll be fine.
  7. jak zwolnić buforowanie używane przez MongoDB? : taka sama odpowiedź jak w 5.

Teraz wydaje mi się, że rozumiem na podstawie tych wszystkich odpowiedzi:

  1. Dla szybszego dostępu lepiej byłoby, aby mongo pasowało do wszystkich wskaźników w pamięci RAM. Jednak w moim przypadku nie mam nic przeciwko indeksom częściowo znajdującym się na dysku, ponieważ mam dość szybki dysk SSD.
  2. Pamięć RAM jest najczęściej używana do buforowania przez mongo.

Biorąc to pod uwagę, spodziewałem się, że mongo spróbuje użyć jak największej ilości pamięci RAM, ale będę w stanie funkcjonować również z niewielką ilością pamięci RAM i pobierając większość rzeczy z dysku. Jednak ograniczyłem pamięć kontenera Docker mongo (na przykład do 8 GB), używając --memoryi --memory-swap, ale zamiast pobierać rzeczy z dysku, mongo po prostu się zawiesiło, gdy tylko zabrakło pamięci.

Jak zmusić mongo do używania tylko dostępnej pamięci i pobierania z dysku wszystkiego, co nie mieści się w pamięci?

Simone Bronzini
źródło
To się nazywa zabójca OOM. MongoDB jest zaprojektowany do działania na sprzęcie towarowym. Nigdy nie uruchomiłbym tego na sztucznie ograniczonych zasobach. Jeśli masz tylko małą bazę danych, MongoDB nie jest idealnym wyborem. Jeśli masz dużą bazę danych (trzy cyfry od Miliona do miliarda wpisów), ograniczanie zasobów to zły wybór. Jak na twój problem: nie możesz mieć ciasta i go zjeść. Wybierać.
Markus W Mahlberg,
Jeśli poprawnie skonfigurowany, MongoDB nie powinien ulec awarii, gdy zabraknie pamięci. Czy możesz potwierdzić konkretną wersję serwera MongoDB i systemu operacyjnego, którego używasz, a także bardziej szczegółowo opisać awarię? Na przykład, czy są jakieś komunikaty w dzienniku MongoDB lub dmesgkorelują z nieoczekiwanym zamknięciem? Najbardziej prawdopodobne jest to w przypadku Dockera, że ​​procesy w kontenerze wykrywają całkowitą dostępną pamięć RAM, a nie limit kontenera.
Stennie,
Jak na MongoDB produkcyjne Uwagi : po uruchomieniu mongodw pojemniku ( lxc, cgroups, Döcker, etc.), które ma nie mieć dostęp do wszystkich pamięci RAM dostępnej w systemie, należy ustawić storage.wiredTiger.engineConfig.cacheSizeGBna wartość mniejszą niż ilość pamięci RAM dostępny w pojemnik. Dokładna ilość zależy od innych procesów uruchomionych w kontenerze, ale zazwyczaj nie powinna przekraczać domyślnej wartości 50% pamięci RAM minus 1 GB.
Stennie,

Odpowiedzi:

9

Zgodnie z BOL MongoDB Tutaj zmieniono w wersji 3.4: Wartości mogą się wahać od 256MBdo 10TBi mogą być a float. Ponadto zmieniła się również wartość domyślna.

Począwszy od 3.4, wewnętrzna pamięć podręczna WiredTiger domyślnie używa większego z następujących:

50% of RAM minus 1 GB, or
256 MB.

Dzięki WiredTigerMongoDB wykorzystuje zarówno WiredTiger, jak internal cache i filesystem cache.

Za pośrednictwem filesystem cacheMongoDB automatycznie wykorzystuje całą wolną pamięć, która nie jest używana przez WiredTiger cacheani przez inne procesy.

Storage.wiredTiger.engineConfig.cacheSizeGB ogranicza wielkość WiredTigerwewnętrznej pamięci podręcznej. System operacyjny użyje dostępnej wolnej pamięci na pamięć podręczną systemu plików, co pozwala pozostać skompresowanym plikom danych MongoDB w pamięci. Ponadto operating systemwykorzysta każdą wolną pamięć RAM do buforowania bloków systemu plików i pamięci podręcznej systemu plików.

Aby pomieścić dodatkowych konsumentów pamięci RAM , konieczne może być zmniejszenie WiredTigerwielkości wewnętrznej pamięci podręcznej.

Więcej informacji na temat WiredTiger Storage Engine i opcji pliku konfiguracyjnego

Md Haidar Ali Khan
źródło
4

Właściwie, jeśli przyjrzysz się uważnie, to nie mongod umiera za „brak pamięci”, to menedżer OOM (brak pamięci) jądra zabija mongod, ponieważ ma największe wykorzystanie pamięci.

Tak, możesz spróbować rozwiązać problem z parametrem konfiguracyjnym monngodb cacheSizeGB , ale w środowisku kontenerowym lepiej jest użyć cgroups, aby ograniczyć zasoby, które uzyskuje którykolwiek z twoich trzech kontenerów.

JJussi
źródło