MongoDB i zestawy danych, które nie mieszczą się w pamięci RAM, bez względu na to, jak mocno się pchasz


12

Jest to bardzo zależne od systemu, ale są prawie pewne, że przeskoczymy obok dowolnego klifu i wpadniemy w Prawdziwe Kłopoty. Jestem ciekawy, jakie są podstawowe zasady dobrego stosunku pamięci RAM do miejsca na dysku. Planujemy następną rundę systemów i musimy dokonać pewnych wyborów dotyczących pamięci RAM, dysków SSD i ilości każdego nowego węzła.

Ale teraz trochę szczegółów wydajności!

Podczas normalnego przepływu pracy w ramach jednego projektu projekt MongoDB zostaje dotknięty bardzo wysokim odsetkiem zapisów (70–80%). Po osiągnięciu drugiego etapu potoku przetwarzania jego odczyt jest niezwykle wysoki, ponieważ musi zduplikować rekordy zidentyfikowane w pierwszej połowie przetwarzania. Jest to przepływ pracy, dla którego stworzono „zachowaj zestaw roboczy w pamięci RAM”, a my projektujemy wokół tego założenia.

Cały zestaw danych jest nieustannie trafiany losowymi zapytaniami ze źródeł pochodzących od użytkowników końcowych; chociaż częstotliwość jest nieregularna, rozmiar jest zwykle dość mały (grupy 10 dokumentów). Ponieważ dotyczy to użytkownika, odpowiedzi muszą znajdować się poniżej progu „znudzonego” wynoszącego 3 sekundy. Ten wzorzec dostępu znacznie rzadziej znajduje się w pamięci podręcznej, więc bardzo prawdopodobne jest, że spowoduje trafienie dysku.

Drugi proces przetwarzania to wysoki odczyt poprzednich przebiegów przetwarzania, które mogą mieć dni, tygodnie, a nawet miesiące, i jest uruchamiany rzadko, ale nadal musi być spakowany. Dostęp do 100% dokumentów z poprzedniego przebiegu przetwarzania będzie możliwy. Podejrzewam, że nie może pomóc w tym ocieplenie pamięci podręcznej.

Rozmiary gotowych dokumentów różnią się znacznie, ale średni rozmiar wynosi około 8 KB.

Wysoki odczyt normalnego przetwarzania projektu zdecydowanie sugeruje użycie replik w celu dystrybucji ruchu Read. Czytałem gdzie indziej, że RAM-GB 1:10 na HD-GB to dobra zasada dla wolnych dysków, ponieważ poważnie rozważamy użycie znacznie szybszych dysków SSD, chciałbym wiedzieć, czy istnieje podobna reguła kciuka za szybkie dyski.

Wiem, że używamy Mongo w taki sposób, że pamięć podręczna - wszystko naprawdę nie będzie latać, dlatego szukam sposobów na zaprojektowanie systemu, który przetrwa takie użycie. Cały zestaw danych będzie prawdopodobnie większość z TB w ciągu pół roku i stale rosnąć.


Często zadawane trudne pytanie.
gWaldo

Wygląda na to, że prawdopodobnie napotkasz problemy z blokadą zapisu, zanim będziesz mógł dostroić się do IO dużo, szczerze mówiąc. Jeśli młotkujesz DB za pomocą operacji zapisu, najprawdopodobniej będziesz trzymać blokady zapisu na tyle długo, że zapytania przestaną działać, niezależnie od tego, jak szybkie jest IO. Coś takiego jak Fusion IO może nieco zmniejszyć blokadę zapisu, ale kupuje tylko trochę czasu, to nie jest prawdziwa poprawka.
MrKurt,

@MrKurt Część tego, co próbuję ustalić, to to, kiedy muszę odłamek, oprócz tego, jak potężne mogę zrobić poszczególne węzły repliki. Moja tymczasowa specyfikacja dotyczy karty SSD opartej na PCIe.
sysadmin1138

Ach, rozumiem. Od samego początku możesz rozważyć dzielenie na fragmenty, często dzielimy na pojedyncze serwery. Pozwala ominąć blokadę zapisu i skutecznie skalować zapisy do wszystkich rdzeni. Ponadto później łatwiej jest przenosić odłamki między serwerami.
MrKurt

Odpowiedzi:


5

To będzie garść drobnych punktów. Niestety nie ma jednej odpowiedzi na twoje pytanie.

MongoDB pozwala jądrze systemu operacyjnego na zarządzanie pamięcią. Oprócz zrzucenia jak największej ilości pamięci RAM na problem, jest tylko kilka rzeczy, które można zrobić, aby „aktywnie zarządzać” zestawem roboczym.

Jedyną rzeczą, którą możesz zrobić, aby zoptymalizować zapisy, jest pierwsze zapytanie o ten rekord (wykonanie odczytu), aby znajdował się on w pamięci roboczej. Pozwoli to uniknąć problemów z wydajnością związanych z globalną blokadą procesu (która ma stać się per-db w wersji 2.2)

Nie ma twardej i szybkiej reguły dla stosunku pamięci RAM do SSD, ale myślę, że surowe operacje IOPS dysków SSD powinny pozwolić ci na znacznie niższy stosunek. Z czubka mojej głowy 1: 3 jest prawdopodobnie najniższą, z którą chcesz się wybrać. Ale biorąc pod uwagę wyższe koszty i niższe wydajności, prawdopodobnie i tak będziesz musiał utrzymać ten współczynnik na niskim poziomie.

Jeśli chodzi o „fazy zapisu a fazy czytania”, czy czytam poprawnie, że po zapisaniu rekord rzadko jest aktualizowany („uaktualniany”)? W takim przypadku warto zorganizować dwa klastry; normalny klaster zapisu i klaster zoptymalizowany pod kątem odczytu dla „starych” danych, które nie zostały zmodyfikowane w [okresie X] . Zdecydowanie włączyłem odczyt niewolników w tym klastrze. (Osobiście poradziłbym sobie z tym, dołączając wartość zmodyfikowaną datą do dokumentów obiektowych bazy danych.)

Jeśli masz możliwość przetestowania obciążenia przed wejściem do Prod, doskonale monitoruj to. MongoDB został napisany przy założeniu, że często będzie wdrażany na maszynach wirtualnych (ich systemy referencyjne znajdują się w EC2), więc nie bój się oddzielić od maszyn wirtualnych.


Podczas przetwarzania tworzony jest początkowy odcinek dokumentu, który jest następnie stale aktualizowany przez różne podetapy w pierwszej części przetwarzania. Zastanawialiśmy się nad możliwością ręcznego wypełnienia przy początkowym tworzeniu, aby zmniejszyć zakres rozszerzania, ale obecnie nasz odsetek blokad zapisu jest na szczęście niski.
sysadmin1138

Rada, aby przeczytać zapis przed zapisaniem go, aby dostać się do pamięci RAM, nie jest dobrą radą. Od 2.0 (połowa 2011 r.) MongoDB przyniosło ustępstwa, jeśli dane, do których ma się uzyskać dostęp, nie znajdują się w pamięci RAM, więc powodujesz dodatkowy odczyt i dodatkową podróż w obie strony do serwera bez powodu, jeśli zrobisz to, ponieważ blokada nie i tak nie będą się odbywać przez ten czas.
Asya Kamsky

13

Ma to stanowić uzupełnienie do innych odpowiedzi zamieszczonych tutaj, które omawiają wiele istotnych elementów, które należy tutaj rozważyć. Istnieje jednak inny, często pomijany, czynnik dotyczący efektywnego wykorzystania pamięci RAM w systemie typu dostępu swobodnego - readahead.

Możesz sprawdzić bieżące ustawienia readahead (w systemie Linux), uruchamiając blockdev --report(zwykle wymaga uprawnień sudo / root). Spowoduje to wydrukowanie tabeli z jednym rzędem dla każdego urządzenia dyskowego. Kolumna RA zawiera wartość readahead. Ta wartość to liczba 512-bajtowych sektorów (chyba że rozmiar sektora nie jest domyślny - zwróć uwagę, że w momencie pisania tego postu nawet dyski o większych rozmiarach są traktowane przez jądro jako 512-bajtowe sektory), które są odczytywane na każdym dostęp do dysku.

Możesz ustawić ustawienie readahead dla danego urządzenia dyskowego, uruchamiając:

blockdev --setra <value> <device name>

Podczas korzystania z oprogramowania RAID opartego na oprogramowaniu należy ustawić głowicę readahead na każdym urządzeniu dyskowym, a także na urządzeniu odpowiadającym kontrolerowi RAID.

Dlaczego to jest ważne? Cóż, readahead używa tego samego zasobu, którego MongoDB próbuje użyć w celu zoptymalizowania twoich odczytów dla dostępu sekwencyjnego - RAM. Kiedy wykonujesz sekwencyjne odczyty na wirujących dyskach (lub urządzeniach, które zachowują się jak wirujące dyski - EBS Patrzę na ciebie), pobieranie pobliskich danych do pamięci RAM może znacznie zwiększyć wydajność, zaoszczędzić na próbach i wysokie ustawienie odpowiednie środowisko może przynieść imponujące wyniki.

W przypadku systemu takiego jak MongoDB, w którym twój dostęp będzie ogólnie dostępem losowym w zbiorze danych, jest to po prostu marnowanie pamięci, którą lepiej wykorzystać gdzie indziej. System, który, jak wspomniano w innym miejscu, zarządza również pamięcią dla MongoDB, zamierza przydzielić część pamięci do ponownego uruchomienia, gdy zostanie o to poproszony, i tym samym pozostawi mniej pamięci RAM dla MongoDB do efektywnego wykorzystania.

Wybór odpowiedniego rozmiaru głowicy jest trudny i zależy od sprzętu, konfiguracji, rozmiaru bloku, rozmiaru paska i samych danych. Jeśli przejdziesz na przykład na dyski SSD, będziesz potrzebować niskiego ustawienia, ale to, jak niskie będzie zależeć od danych.

Wyjaśniając: chcesz się upewnić, że readahead jest wystarczająco wysoki, aby pobrać pełny pojedynczy dokument i nie musisz wracać na dysk. Weźmy wspomnianą medianę o wielkości 8k - ponieważ sektory na dysku mają zwykle 512 bajtów, odczytanie całego dokumentu bez żadnych problemów wymagałoby 16 dostępu do dysku. Gdybyś miał 16 lub więcej sektorów, przeczytałbyś cały dokument z tylko jedną podróżą na dysk.

W rzeczywistości, ponieważ segmenty indeksów MongoDB mają rozmiar 8k, nigdy nie będziesz chciał ustawić readahead poniżej 16, lub odczytanie w jednym segmencie zajmie 2 dostępy do dysku. Ogólna dobra praktyka to zacząć od obecnego ustawienia, zmniejszyć je o połowę, a następnie ponownie ocenić wykorzystanie pamięci RAM i operacji wejścia / wyjścia i przejść od tego momentu.


1
Cenne informacje, które na pewno się przydadzą, gdy zdobędziemy sprzęt. Dzięki!
sysadmin1138

3

Należy rozważyć użycie replik do zapytań użytkowników końcowych i wykonanie pracy na innych komputerach.

Używając reguły 1:10, patrzysz na około 128 GB pamięci RAM na 1 TB miejsca na dysku; Chociaż niektóre niedrogie dyski SSD twierdzą, że osiągają> 60 000 IOPS, rzeczywiste liczby mogą się nieco różnić, a także to, czy używasz RAID z dyskami SSD, czy nie, a jeśli tak, to karta RAID jest również niezwykle ważna .

W momencie pisania tego postu przejście z 128 GB pamięci RAM DDR3 ECC na 256 GB wydaje się być około 2000 USD dodatkowych na serwerze Intel 1U, a to da ci stosunek 1: 5 z 1 TB danych, co moim zdaniem byłoby jeszcze lepszy stosunek. Jeśli potrzebujesz, aby twoje obciążenie zostało ukończone tak szybko, jak to możliwe, na pewno pomoże więcej pamięci RAM, ale czy to naprawdę tak pilne?

Będziesz musiał także dostrajać system plików, coś w rodzaju „noatime, data = writeback, nobarrier” na ext4, i może być konieczne wprowadzenie drobnych poprawek ustawień jądra, aby wycisnąć jak najwięcej wydajności z twojego system.

Jeśli korzystasz z RAID, RAID-10 będzie całkiem dobrym wyborem, a przy odpowiednim kontrolerze RAID będzie oferować całkiem zwiększoną wydajność, ale o połowę dostępną przestrzeń. Możesz także spojrzeć na RAID50, jeśli chcesz przyzwoitego wzrostu wydajności bez zmniejszenia o połowę dostępnej przestrzeni. Ryzyko związane z uruchomieniem macierzy RAID polega na tym, że nie masz już dostępu do TRIM na swoich dyskach, co oznacza, że ​​od czasu do czasu musisz przenieść dane, rozbić RAID, PRZYCIĄĆ dyski i ponownie utworzyć RAID.

Ostatecznie musisz zdecydować, ile chcesz złożoności, ile pieniędzy chcesz wydać i jak szybko chcesz przetwarzać obciążenie pracą. Oceniłbym również, czy MongoDB jest idealną bazą danych do użycia, ponieważ nadal możesz używać Mongo do zapytań użytkowników końcowych, które wymagają szybkich odpowiedzi, ale użyj czegoś innego do przetwarzania danych, które nie muszą być gotowe w ciągu kilku sekund , a także może ułatwić rozłożenie obciążenia na wiele komputerów.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.