Co się stanie, jeśli w MongoDB będzie za dużo wstawek? Jak zapewnić przechowywanie wszystkich danych?

24

Używam MongoDB do przechowywania okresowo zmierzonych wartości. Co ~ 100 ms wiązka wartości jest wstawiana jako dokument. Działa dobrze, ale martwię się o problemy z wydajnością. (Używam bezpiecznych wstawek, wygląda na to, że w PyMongo jest to ustawienie domyślne).

Co się stanie, jeśli będzie więcej wkładek na sekundę niż mongod jest w stanie zapisać na dysku twardym? Czy będzie jakieś ostrzeżenie, czy po prostu po cichu zawiedzie?

Czy istnieje metoda monitorowania obciążenia zapisu? Znalazłem tylko db.serverStatus().writeBacksQueuedto, co zawsze ma wartość false, gdy go nazywam. Jak mogę sprawdzić, ile danych muszę wstawić, aby wypełnić kolejkę zapisu?

mongostatwyświetla zamki. Czy powinienem się tym martwić?

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
  *117     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:6.5%          0       0|0     0|0   124b     6k     2  SLV   09:58:10 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:0.8%          0       0|0     0|0   124b     6k     2  SLV   09:58:11 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:4.2%          0       0|0     0|0   124b     6k     2  SLV   09:58:1

Czy muszę się martwić blokadami zapisu? Co dzieje się z wkładką w okresie blokowania zapisu? Czy jest w kolejce i jest przechowywany później?

Mam na myśli prostą konfigurację replikacji przy użyciu jednego urządzenia nadrzędnego i jednego urządzenia podrzędnego. Czy początkowa synchronizacja lub proces ponownej synchronizacji blokuje bazy danych?

(Używam wersji 2.4.3.)

Aktualizacja: Myślę, że częściowo odpowiedziałem na własne pytanie. Udało mi się uzyskać do 12.000 wstawek na sekundę przy użyciu prostej pętli while podczas wstawiania małego dokumentu testowego. Ale qr | qw nadal pokazuje, że kolejka odczytu i zapisu jest nadal pusta:

insert  query update delete getmore command flushes mapped  vsize    res faults       locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
 11234     *0      2     *0    1563     1|0       1  21.9g  44.3g  1.22g      0    testdb:58.9%          0       1|0     1|1   797k   980k     6  PRI   10:26:32 
 12768     *0      2     *0    1284     1|0       0  21.9g  44.3g  1.22g      0    testdb:58.0%          0       0|0     0|1   881k     1m     6  PRI   10:26:33 
 12839     *0      2     *0    1231     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.3%          0       0|0     0|1   883k     1m     6  PRI   10:26:34 
 12701     *0      2     *0     910     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   858k     1m     6  PRI   10:26:35 
 12241     *0      2     *0    1206     1|0       0  21.9g  44.3g  1.22g      0    testdb:56.7%          0       0|0     0|0   843k     1m     6  PRI   10:26:36 
 11581     *0      2     *0    1406     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   811k     1m     6  PRI   10:26:37 
  8719     *0      2     *0    1210     1|0       0  21.9g  44.3g  1.22g      0    testdb:43.8%          0       0|0     0|1   618k   762k     6  PRI   10:26:38 
 11429     *0      2     *0    1469     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.6%          0       0|0     0|1   804k   993k     6  PRI   10:26:39 
 12779     *0      2     *0    1092     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.2%          0       1|0     0|1   872k     1m     6  PRI   10:26:40 
 12757     *0      2     *0     436     1|0       0  21.9g  44.3g  1.22g      0    testdb:59.7%          0       0|0     0|1   838k   432k     6  PRI   10:26:41 

Podejrzewam, że oznacza to, że same wstawki nie spowodują wielu problemów: „Kolejki będą miały tendencję do gwałtownego wzrostu, jeśli wykonujesz wiele operacji zapisu wraz z innymi ciężkimi operacjami zapisu, takimi jak usuwanie dużych odległości”. (znaleziono tutaj ]

Moje otwarte pytanie: co stanie się z moimi danymi, jeśli kolejka zapisu wzrośnie w dłuższej perspektywie?

lędźwiowy
źródło

Odpowiedzi:

25

Odpowiedziałeś tutaj na niektóre z twoich pytań, w szczególności masz przyzwoity pomysł na temat równania blokady zapisu - 12 000 wstawek / s pozwala uzyskać ~ 60% blokadę zapisu. Jest to rozsądny poziom, aby uzyskać stałą wydajność - będziesz mieć spory, a niektóre operacje będą nieco wolniejsze, ale naprawdę chcesz zacząć martwić się o około 80% - jak wiele rzeczy, kiedy zaczniesz przekraczać 80% dostępnych pojemność zaczniesz częściej zadawać problemy.

Jeśli chodzi o inne wąskie gardła, a zwłaszcza to, jak szybko możesz zapisywać na dysk - może to powodować problemy, ale aby spojrzeć na odpowiednie statystyki w czasie, zaleciłbym zainstalowanie MMS z wtyczką munin-node, aby uzyskać statystyki sprzętowe i we / wy dodatek do statystyk MongoDB.

Gdy to zrobisz, metryki, na które warto zwrócić uwagę, to:

  • Średni czas płukania (tyle trwa okresowa synchronizacja MongoDB z dyskiem)
  • IOStaty w zakładce sprzętowej (w szczególności IOWait)
  • Błędy strony (jeśli Twój dysk jest zajęty zapisami i musisz odczytać dane, będą konkurować o ograniczone zasoby)

To trochę skomplikowane, ale oto podstawowy pomysł:

  • Gdy zacznie się zwiększać średni czas spłukiwania, należy się martwić
  • Jeśli dostanie się do wielu sekund zakresu, prawdopodobnie jesteś na granicy (choć zależy to od ilości zapisanych danych i prędkości dysku)
  • Jeśli zbliży się do 60 sekund, wydajność ulegnie znacznemu pogorszeniu (spłukiwanie odbywa się co 60 sekund, więc w zasadzie byłyby w kolejce)
  • High IOWait również będzie obniżać wydajność, szczególnie jeśli będziesz musiał czytać z dysku w dowolnym momencie
  • Dlatego ważne będzie również sprawdzenie poziomów błędów strony

Drugim elementem tej układanki, o którym jeszcze nie wspomnieliśmy, jest dziennik. Będzie to również utrwalanie danych na dysku (domyślnie co 100 ms), a więc będzie zwiększało obciążenie dysku, jeśli jest on na tym samym woluminie. Dlatego jeśli widzisz duże wykorzystanie dysku, dobrym pomysłem byłoby przeniesienie dziennika na inny dysk.

Nie ma prawdziwych „magicznych liczb” do utrzymania, w większości przypadków są one względne, więc uzyskaj dobrą linię bazową dla normalnego ruchu, sprawdź, czy sytuacja się poprawia, i może przetestuj obciążenie, aby zobaczyć, jakie są twoje limity i kiedy rzeczy zacznij degradować, a będziesz w dobrej formie.

Po tych wszystkich wstępach do niektórych pytań:

Co się stanie, jeśli będzie więcej wkładek na sekundę, niż mongod jest w stanie zapisać na dysku twardym? Czy będzie jakieś ostrzeżenie, czy po prostu po cichu zawiedzie?

Jeśli zaczniesz obciążać dysk do poziomów opisanych powyżej, w końcu wszystko zwolni iw pewnym momencie (i będzie to zależeć od limitów czasu, jak potężny jest twój sprzęt, jak radzisz sobie z wyjątkami), twoje zapisy zakończą się niepowodzeniem - jeśli używasz najnowszej wersji pymongo, wówczas domyślnie będziesz używać bezpiecznych zapisów, które następnie zakończą się niepowodzeniem. Jeśli chcesz być trochę bardziej paranoikiem, od czasu do czasu możesz zrobić problem z zapisem j: true, który będzie czekał na zwrócenie OK, dopóki zapis nie dotrze do dziennika (tj. Na dysku). Będzie to oczywiście wolniejsze niż normalny bezpieczny zapis, ale będzie to natychmiastowe wskazanie problemów związanych z pojemnością dysku, a można go użyć do blokowania / kolejkowania innych operacji i zasadniczo działać jako przepustnica, aby uniemożliwić bazę danych przytłoczony.

Mam na myśli prostą konfigurację replikacji przy użyciu jednego urządzenia nadrzędnego i jednego urządzenia podrzędnego. Czy początkowa synchronizacja lub proces ponownej synchronizacji blokuje bazy danych?

Myślę, że omówiłem ogólnie blokowanie na początku, ale aby odpowiedzieć konkretnie na ten fragment: Po pierwsze, upewnij się, że używasz zestawu replik , a nie master / slave. Implementacja master / slave jest przestarzała i nie jest zalecana do ogólnego użytku. Jeśli chodzi o początkową synchronizację, doda trochę obciążenia do podstawowej pod względem odczytu, ale nie pod względem zapisów, więc powinieneś być w porządku pod względem blokowania.

Co stanie się z moimi danymi, jeśli kolejka zapisu wzrośnie w dłuższej perspektywie?

Jak zapewne możesz stwierdzić na podstawie powyższego wyjaśnienia, odpowiedź zależy w dużej mierze od tego, jak piszesz swoją aplikację, jak decydujesz się na potwierdzenie zapisu i ile masz dostępnej pojemności. Zasadniczo możesz być tak bezpieczny, jak chcesz, jeśli chodzi o zapisywanie na dysku w MongoDB, ale występuje kompromis wydajności, jak wspomniano w j:truepowyższej dyskusji.

Ogólnie rzecz biorąc, chcesz ustalić swój czynnik ograniczający - czy to blokowanie, prędkość dysku itp., A następnie śledzić poziomy w czasie i skalować (dzielenie) lub w górę (lepszy sprzęt), zanim osiągniesz twardy limit i zobaczysz problemy z wydajnością.

Ostatnia rzecz, db.serverStatus().writeBacksQueuedto tak naprawdę metryka, która zawsze będzie niezerowa w podzielonym środowisku i ma do czynienia z upewnieniem się, że zapisy do fragmentu podczas migracji są odpowiednio obsługiwane (obsługiwane przez odbiornik zapisu zwrotnego ). Stąd jest to przede wszystkim czerwony śledź - nie ma to nic wspólnego z ogólną wielkością zapisu.

Adam C.
źródło