Używamy MongoDB od kilku tygodni, ogólny trend, który widzieliśmy, był taki, że mongodb zużywa zbyt dużo pamięci (znacznie więcej niż cały rozmiar zestawu danych + indeksy).
Przeczytałem już to pytanie i to pytanie , ale wydaje się, że żadne nie odnosi się do problemu, z którym się spotkałem, w rzeczywistości wyjaśniają to, co zostało już wyjaśnione w dokumentacji.
Poniżej przedstawiono wyniki poleceń htop i show dbs .
Wiem, że mongodb używa IO odwzorowanego w pamięci, więc w zasadzie system operacyjny obsługuje buforowanie rzeczy w pamięci, a mongodb teoretycznie powinien zwolnić swoją pamięć podręczną, gdy inny proces żąda wolnej pamięci , ale z tego, co widzieliśmy, tak nie jest.
OOM zaczyna zabijać inne ważne procesy, np. Postgres, redis itp. (Jak widać, aby rozwiązać ten problem, zwiększyliśmy pamięć RAM do 183 GB, co teraz działa, ale jest dość drogie. Mongo używa ~ 87 GB pamięci RAM, prawie czterokrotnie większy niż cały zestaw danych)
Więc,
- Czy tak duże zużycie pamięci jest naprawdę oczekiwane i normalne? (Zgodnie z dokumentacją WiredTiger zużywa maksymalnie ~ 60% pamięci RAM na swoją pamięć podręczną, ale biorąc pod uwagę rozmiar zestawu danych, czy ma nawet wystarczającą ilość danych, aby móc zabrać 86 GB pamięci RAM?)
- Nawet jeśli spodziewane jest użycie pamięci, dlaczego Mongo nie zwolni przydzielonej pamięci, jeśli inny proces zacznie żądać więcej pamięci? Różne inne działające procesy były ciągle zabijane przez linux oom, w tym sam mongodb, zanim zwiększyliśmy pamięć RAM i spowodowało to, że system był całkowicie niestabilny.
Dzięki !
źródło
Odpowiedzi:
Okej, więc po zapoznaniu się ze wskazówkami podanymi przez loicmathieu i jstell i nieco pogrzebaniu, oto rzeczy, które dowiedziałem się o MongoDB za pomocą silnika pamięci WiredTiger. Kładę to tutaj, jeśli ktoś napotkał te same pytania.
Wątki użycia pamięci, o których wspomniałem, wszystkie należały do 2012-2014, wszystkie były wcześniejszymi WiredTiger i opisują zachowanie oryginalnego silnika pamięci MMAPV1, który nie ma osobnej pamięci podręcznej ani obsługi kompresji.
Ustawienia pamięci podręcznej WiredTiger kontrolują tylko rozmiar pamięci używanej bezpośrednio przez silnik pamięci WiredTiger (nie całkowitą pamięć używaną przez mongod). Wiele innych rzeczy potencjalnie zajmuje pamięć w konfiguracji MongoDB / WiredTiger, takich jak:
WiredTiger kompresuje pamięć dyskową, ale dane w pamięci są nieskompresowane.
WiredTiger domyślnie nie synchronizuje danych przy każdym zatwierdzeniu , więc pliki dziennika znajdują się również w pamięci RAM, co odbija się na pamięci. Wspomniano również, że w celu efektywnego wykorzystania We / Wy, WiredTiger łączy żądania We / Wy (brak pamięci podręcznej), co również wydaje się zajmować trochę pamięci RAM (w rzeczywistości brudne strony (strony, które uległy zmianie / aktualizacji) mają listę aktualizacji na nich przechowywane w współbieżnym SkipList ).
WiredTiger przechowuje wiele wersji rekordów w swojej pamięci podręcznej (Kontrola współbieżności wielu wersji, operacje odczytu uzyskują dostęp do ostatniej zatwierdzonej wersji przed ich działaniem).
WiredTiger Przechowuje sumy kontrolne danych w pamięci podręcznej.
Sam MongoDB zużywa pamięć do obsługi otwartych połączeń, agregacji, kodu na serwerze itp .
Biorąc pod uwagę te fakty, poleganie na
show dbs;
nim nie było technicznie poprawne, ponieważ pokazuje jedynie skompresowany rozmiar zestawów danych.Aby uzyskać pełny rozmiar zestawu danych, można użyć następujących poleceń.
Wyniki są następujące:
Wygląda więc na to, że rzeczywisty rozmiar zestawu danych + jego indeksy zajmują około 68 GB tej pamięci.
Biorąc to wszystko pod uwagę, wydaje się, że użycie pamięci jest teraz dość spodziewane, dobrą rzeczą jest to, że można całkowicie ograniczyć rozmiar pamięci podręcznej WiredTiger, ponieważ dość skutecznie obsługuje operacje we / wy (jak opisano powyżej).
Pozostaje również problem OOM, aby rozwiązać ten problem, ponieważ nie mieliśmy wystarczających zasobów, aby zabrać mongodb, obniżyliśmy oom_score_adj, aby na razie uniemożliwić OOM zabijanie ważnych procesów (co oznacza, że powiedzieliśmy OOM, aby nie zabijał naszego pożądane procesy ).
źródło
oom_score_adj
rozwiązanie było najlepszą rzeczą, jaką udało ci się wymyślić?Nie sądzę, żebyś miał problem z MongoDB, ponieważ jstell powiedział ci, że MongoDB z WiredTiger zużyje 50% dostępnej pamięci, więc jeśli zwiększysz pamięć RAM twojego serwera, zajmie to więcej pamięci.
Ponieważ jest to więcej niż rozmiar indeksów DB +, należy pamiętać, że WiredTiger kompresuje bazę danych na dysku, a także używa dzienników migawek do rejestrowania zmian w dokumentach. Tak więc rzeczywisty rozmiar WiredTiger to rozmiar za pomocą show dbs * kompresja_racja + rozmiar dzienników migawek. Tak więc prawie niemożliwe jest dokładne określenie oczekiwanego rozmiaru.
Należy także pamiętać, że narzędzia, takie jak
top
,ps
,htop
nie wyświetla pamięć rzeczywiście używany przez aplikację, referen do tego SOW pytanie o szczegóły: https://stackoverflow.com/questions/131303/how-to-measure-actual-memory -usage-of-a-application-or-processWróćmy do problemu. Masz inne narzędzia uruchomione na tym samym hoście, a OOM je zabija. Nie znam Linux OOM, ale czy jesteś pewien, że zabija ich z powodu MongoDB lub… właśnie z ich powodu (może zabija Postgres, ponieważ Postgres zabrał zbyt dużo pamięci).
W każdym razie, jako najlepszą praktykę, jeśli masz dużą bazę danych Mongo, nie instaluj jej na hoście współdzielonym z innymi bazami danych lub będziesz miał wiele trudności, na wypadek, gdybyś miał problem taki jak ten, który tu opisujesz, aby wiedzieć kto naprawdę powoduje problem na hoście.
źródło
Dokumenty
Możesz przeczytać podstawowe obawy dotyczące pamięci MongoDB, a także krótką dyskusję na temat sprawdzania użycia pamięci .
Przegląd wykorzystania pamięci
Polecenie
db.serverStatus()
( dokumenty ) może zapewnić przegląd użycia pamięci, w szczególności:Jak duże są twoje indeksy?
db.stats()
możemy wyświetlić całkowity rozmiar wszystkich indeksów, ale możemy również uzyskać szczegółowe informacje o pojedynczej kolekcji przy użyciudb.myCollection.stats()
Na przykład to polecenie porówna rozmiary indeksów dla każdej kolekcji :
Teraz możemy spojrzeć na szczegóły tej ogromnej kolekcji, aby zobaczyć, który z jej indeksów jest najbardziej kosztowny:
Dzięki temu możemy lepiej zrozumieć, gdzie możliwe są oszczędności.
(W tym przypadku mieliśmy indeks,
createTime
który był raczej ogromny - jeden wpis na dokument - i zdecydowaliśmy, że możemy bez niego żyć).źródło
createTime
indeks był problematyczny, ponieważ był unikalny dla każdego dokumentu, a ta kolekcja była ogromna. Indeksowanie pozostałych pól było w porządku, ponieważ było mniej unikatowych wartości (wartości były grupowane).