Gdzie mongodb znajduje się w twierdzeniu CAP?

121

Wszędzie, gdzie spojrzę, widzę, że MongoDB to CP. Ale kiedy się zagłębiam, widzę, że ostatecznie jest to spójne. Czy to CP, kiedy używasz safe = true? Jeśli tak, czy to oznacza, że ​​kiedy piszę z safe = true, wszystkie repliki zostaną zaktualizowane przed uzyskaniem wyniku?

Gluz
źródło

Odpowiedzi:

104

MongoDB jest domyślnie silnie spójny - jeśli wykonasz zapis, a następnie odczytasz, zakładając, że zapis się powiódł, zawsze będziesz w stanie odczytać wynik właśnie przeczytanego zapisu. Dzieje się tak, ponieważ MongoDB jest systemem z jednym wzorcem i wszystkie odczyty domyślnie przechodzą do podstawowego. Jeśli opcjonalnie włączysz odczytywanie z elementów pomocniczych, MongoDB stanie się ostatecznie spójne, gdzie możliwe będzie odczytanie nieaktualnych wyników.

MongoDB uzyskuje również wysoką dostępność dzięki automatycznemu przełączaniu awaryjnemu w zestawach replik: http://www.mongodb.org/display/DOCS/Replica+Sets

stbrody
źródło
13
Według aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads, nawet jeśli czytasz z głównego węzła w zestawie replik, możesz uzyskać nieaktualne lub brudne dane. Czy więc MongoDB jest silnie spójny?
Mike Argyriou
3
Niesamowite eksperymenty Kyle'a. To naprawdę poluje na mongo. Zastanawiam się, czy są systemy produkcyjne, na przykład wykorzystujące MongoDB do wykonywania transakcji płatniczych? Jeśli to tylko osobista strona internetowa, komu zależy na silnej spójności.
xin
5
Tak dla przypomnienia, MongoDB v3.4 przeszedł test zaprojektowany przez Kyle'a, więc tak, MongoDB jest bardzo spójny, nawet z ReplicaSet i Sharding: mongodb.com/mongodb-3.4-passes-jepsen-test
Maxime Beugnet
2
Ta odpowiedź może być nieco zbyt uproszczona, ponieważ MongoDB może od czasu do czasu poświęcać dostępność, w zależności od konfiguracji. JoCa lepiej wyjaśnia sytuacje, w których zachowuje się CA / CP / AP
PaoloC
37

Zgadzam się z postem Luccas. Nie możesz po prostu powiedzieć, że MongoDB to CP / AP / CA, ponieważ w rzeczywistości jest to kompromis między C, A i P, w zależności od konfiguracji bazy danych / sterownika i rodzaju awarii : oto podsumowanie wizualne, a poniżej bardziej szczegółowe wyjaśnienie.

    Scenario                   | Main Focus | Description
    ---------------------------|------------|------------------------------------
    No partition               |     CA     | The system is available 
                               |            | and provides strong consistency
    ---------------------------|------------|------------------------------------
    partition,                 |     AP     | Not synchronized writes 
    majority connected         |            | from the old primary are ignored                
    ---------------------------|------------|------------------------------------
    partition,                 |     CP     | only read access is provided
    majority not connected     |            | to avoid separated and inconsistent systems

Konsystencja:

MongoDB jest silnie spójne, gdy używasz pojedynczego połączenia lub prawidłowego poziomu problemów zapisu / odczytu ( co będzie kosztować szybkość wykonywania ). Gdy tylko nie spełnisz tych warunków (zwłaszcza podczas odczytu z repliki pomocniczej), MongoDB staje się ostatecznie spójne.

Dostępność:

MongoDB uzyskuje wysoką dostępność dzięki zestawom replik . Gdy tylko podstawowa ulegnie awarii lub stanie się niedostępna w innym przypadku, wtórne części określą nową, która będzie ponownie dostępna. Ma to wadę: każdy zapis, który został wykonany przez starą wersję podstawową, ale nie został zsynchronizowany z serwerami wtórnymi, zostanie wycofany i zapisany w pliku wycofywania, gdy tylko ponownie połączy się z zestawem (stara wersja podstawowa jest teraz). Tak więc w tym przypadku poświęca się pewną spójność ze względu na dostępność.

Tolerancja partycji:

Dzięki zastosowaniu wspomnianych zestawów replik MongoDB osiąga również tolerancję partycji: tak długo, jak ponad połowa serwerów zestawu replik jest połączona ze sobą, można wybrać nowy podstawowy . Czemu? Aby zapewnić, że dwie oddzielne sieci nie mogą jednocześnie wybrać nowej sieci podstawowej. Gdy nie jest podłączona wystarczająca liczba modułów wtórnych, nadal można z nich odczytywać (ale spójność nie jest zapewniona), ale nie pisać. Zestaw jest praktycznie niedostępny ze względu na spójność.

JoCa
źródło
Więc jeśli używam prawidłowego poziomu problemów z zapisem / odczytem, ​​oznacza to, że wszystkie wroty i odczyty trafiają do podstawowego (jeśli dobrze zrozumiałem), więc co dokładnie robią drugorzędne? Po prostu siedzieć w trybie gotowości na wypadek, gdyby podstawowa padła?
tomer.z
@ tomer.z możesz zechcieć przeczytać tę sekcję podręcznika: Do czytania możesz używać programów dodatkowych. Jeśli używasz „większości” poziomu odczytu, odczyt będzie ważny, gdy tylko większość członków potwierdzi przeczytanie. To samo dotyczy „większości” poziomu zapisu. Jeśli używasz „większości” poziomów obaw dla obu, masz spójną bazę danych. Możesz przeczytać więcej na ten temat w instrukcji .
JoCa
18

Gdy pojawił się genialny nowy artykuł , a także kilka niesamowitych eksperymentów Kyle'a w tej dziedzinie, należy zachować ostrożność podczas oznaczania MongoDB i innych baz danych jako C lub A.

Oczywiście CAP pomaga wyśledzić bez większej ilości słów, co w niej dominuje baza danych, ale ludzie często zapominają, że C w CAP oznacza na przykład spójność atomową (linearyzowalność). I to sprawiło mi wiele bólu, aby zrozumieć, kiedy próbowałem dokonać klasyfikacji. Więc poza tym, że MongoDB daje silną spójność, to nie znaczy, że jest C. W ten sposób, jeśli zrobi się te klasyfikacje, polecam również bardziej szczegółowo opisać, jak to faktycznie działa, aby nie pozostawiać wątpliwości.

Luccas
źródło
10

Tak, to CP podczas używania safe=true. Oznacza to po prostu, że dane trafiły na dysk wzorcowy. Jeśli chcesz się upewnić, że dotarł również do jakiejś repliki, spójrz na parametr „w = N”, gdzie N to liczba replik, w których dane mają zostać zapisane.

zobacz to i to, aby uzyskać więcej informacji.

Jan Prieser
źródło
3

Nie jestem pewien co do P jak Mongo. Wyobraź sobie sytuację:

  • Twoja replika zostanie podzielona na dwie partycje.
  • Pisma są kontynuowane po obu stronach, gdy wybierano nowych mistrzów
  • Partycja została rozwiązana - wszystkie serwery są teraz ponownie połączone
  • Dzieje się tak, że wybierany jest nowy master - ten, który ma najwyższy oplog, ale dane z drugiego mastera są przywracane do wspólnego stanu przed partycją i są zrzucane do pliku w celu ręcznego odzyskania
  • wszystkie drugorzędne dogrywają nowego mistrza

Problem polega na tym, że rozmiar pliku zrzutu jest ograniczony i jeśli masz partycję przez długi czas, możesz utracić dane na zawsze.

Można powiedzieć, że to mało prawdopodobne - tak, chyba że w chmurze, gdzie jest to częstsze niż mogłoby się wydawać.

Na tym przykładzie byłbym bardzo ostrożny przed przypisaniem jakiejkolwiek litery do jakiejkolwiek bazy danych. Jest tak wiele scenariuszy, a implementacje nie są idealne.

Jeśli ktoś wie, czy ten scenariusz został rozwiązany w późniejszych wydaniach Mongo, skomentuj! (Od jakiegoś czasu nie śledzę wszystkiego, co się działo ..)

kubal5003
źródło
2
Protokół wyborów MongoDB został zaprojektowany tak, aby mieć (co najwyżej) jedną prawybór. Podstawowy może zostać wybrany (i utrzymany) tylko przez ścisłą większość skonfigurowanych członków z prawem głosu z zestawu replik (n / 2 + 1). W przypadku partycji sieciowej tylko jedna strefa (z większością głosów członków) może wybrać partycję podstawową; poprzedni prawybory w partycji mniejszościowej ustąpią i staną się drugorzędnymi. Tak zawsze działały repliki. W przypadku, gdy poprzedni główny zaakceptował zapisy, które nie zostały zreplikowane, zostaną one wycofane (zapisane na dysku), gdy ten element członkowski ponownie dołączy do zestawu replik.
Stennie
2

Mongodb nigdy nie pozwala na pisanie do drugorzędnych. Umożliwia opcjonalne odczyty z pomocniczego, ale nie zapisuje. Więc jeśli twoja podstawowa ulegnie awarii, nie możesz pisać, dopóki druga nie stanie się ponownie podstawowa. W ten sposób poświęcasz wysoką dostępność w twierdzeniu CAP. Utrzymując odczyty tylko z poziomu podstawowego, możesz uzyskać silną spójność.

sn.anurag
źródło
2

MongoDB wybiera spójność zamiast dostępności, gdy istnieje partycja. Oznacza to, że gdy istnieje partycja (P), wybiera spójność (C) zamiast dostępności (A).

Aby to zrozumieć, zrozummy, jak działa MongoDB zestaw replik. Zestaw replik ma jeden węzeł podstawowy. Jedynym „bezpiecznym” sposobem zatwierdzania danych jest zapisywanie w tym węźle, a następnie czekanie, aż dane zostaną zatwierdzone do większości węzłów w zestawie. (zobaczysz tę flagę dla w = większość podczas wysyłania zapisów)

Partycja może wystąpić w dwóch scenariuszach w następujący sposób:

  • Kiedy węzeł główny przestanie działać: system stanie się niedostępny do momentu wybrania nowego węzła podstawowego.
  • Gdy węzeł główny traci połączenie ze zbyt wielu węzłów drugorzędnych: system staje się niedostępny. Inne drugorzędne będą próbowały wybrać nową podstawową, a obecna podstawowa ustąpi.

Zasadniczo za każdym razem, gdy pojawi się partycja i MongoDB musi zdecydować, co zrobić, wybierze spójność zamiast dostępności. Przestanie przyjmować zapisy do systemu, dopóki nie uzna, że ​​może je bezpiecznie zakończyć.

Rajneesh Prakash
źródło
Przestanie przyjmować zapisy do systemu, dopóki nie uwierzy, że może bezpiecznie je zakończyć. ” A co z odczytami ? Czy pozostanie dostępne do odczytu w tym czasie?
Josh
1

Mongodb zapewnia spójność i tolerancję partycji .

W kontekście rozproszonych (NoSQL) baz danych oznacza to, że zawsze będzie istniał kompromis między spójnością a dostępnością. Dzieje się tak, ponieważ systemy rozproszone są zawsze odporne na partycje (tj. Po prostu nie byłaby rozproszoną bazą danych, gdyby nie była tolerancyjna na partycje).

Spójność - system w końcu stanie się spójny. Prędzej czy później dane rozprzestrzenią się wszędzie, gdzie powinny, ale system będzie nadal otrzymywać dane wejściowe i nie będzie sprawdzać spójności każdej transakcji, zanim przejdzie do następnej.

Dostępność - domyślnie klient Mongo DB (sterownik MongoDB) wysyła wszystkie żądania odczytu / zapisu do węzła wiodącego / głównego. Sprawia, że ​​system jest spójny, ale niedostępny z powodu: - Jeśli lider odłączy się od klastra, wybranie nowego lidera zajmuje kilka sekund. Tak więc, uniemożliwiając zapis i odczyt w tym czasie.

Satakshi Pandey
źródło