Co tak naprawdę oznacza brak zgodności MongoDB z kwasem przed v4?

Nie jestem ekspertem od baz danych i nie mam formalnego wykształcenia informatycznego, więc proszę o cierpliwość. Chcę poznać rodzajeprawdziwego świata negatywnych rzeczy, które mogą się zdarzyć, jeśli użyjesz starej wersjiMongoDB przed v4 , które nie były zgodne zACID . Dotyczy to każdej bazy danych ACID noncompliant.

Rozumiem, że MongoDB może wykonywać operacje atomowe , ale nie " wspierają tradycyjnych blokad i złożonych transakcje", głównie ze względów wydajnościowych. Rozumiem również znaczenie transakcji bazodanowych i przykład, kiedy twoja baza danych jest dla banku, i aktualizujesz kilka rekordów, które muszą być zsynchronizowane, chcesz, aby transakcja powróciła do stanu początkowego, jeśli jest przerwa w zasilaniu, więc kredyt równa się zakup, itp.

Ale kiedy wchodzę w rozmowy o MongoDB, Ci z nas, którzy nie znają szczegółów technicznych, jak bazy danych są faktycznie implementowane zacznij rzucać wokół wypowiedzi typu:

MongoDB jest znacznie szybszy niż MySQL i Postgres, ale jest mała szansa, jak 1 na milion, że "nie będzie poprawnie zapisywać".

Ta część "nie zapisuje poprawnie" odnosi się do tego zrozumienia: jeśli wystąpi przerwa w zasilaniu w momencie pisania do MongoDB, istnieje szansa na konkretny rekord( powiedzmy, że śledzisz przegląd stron w dokumentach z 10 atrybutami Każdy), że jeden z dokumentów zapisał tylko 5 atrybutów ... co oznacza, że z czasem liczniki odwiedzin stron będą "lekko" wyłączone. Nigdy nie dowiesz się, jak bardzo, wiesz, że będą w 99,999% poprawne, ale nie w 100%. Dzieje się tak, ponieważ, o ile nie uczyniliście tego specjalnie operacją atomową mongodb, operacja ta nie ma gwarancji, że będzie atomowa.

Więc moje pytanie brzmi, jaka jest prawidłowa interpretacja kiedy i dlaczego MongoDB może nie "zapisać poprawnie"? Jakich części kwasu nie zaspokaja i pod jakim okoliczności, a skąd wiesz, kiedy to 0,001% Twoich danych jest wyłączone? Nie da się tego jakoś naprawić? Jeśli nie, oznacza to, że nie powinieneś przechowywać takich rzeczy jak tabela users W MongoDB, ponieważ rekord może nie zostać zapisany. Ale z drugiej strony, ten 1/1, 000, 000 użytkownik może po prostu "spróbować zarejestrować się ponownie", nie?

Po prostu szukam może listy kiedy / dlaczego negatywne rzeczy dzieją się z acid noncompliant bazy danych jak MongoDB, a najlepiej, jeśli istnieje standardowe obejście (jak Uruchom zadanie w tle, aby wyczyścić dane lub użyj tylko SQL do tego, itp.).

Author: Dan Dascalescu, 2011-08-22

10 answers

Jedną z rzeczy, które tracisz z MongoDB, są transakcje z wieloma zbiorami (tabelami). Modyfikatory Atomic w MongoDB mogą działać tylko na jednym dokumencie.

Jeśli musisz usunąć element z inwentarza i dodać go do czyjegoś zamówienia w tym samym czasie - nie możesz. chyba, że te dwie rzeczy-inwentarz i zamówienia-istnieją w tym samym dokumencie(czego prawdopodobnie nie mają).

Napotkałem ten sam problem w aplikacji, nad którą pracuję i miałem dwa możliwe rozwiązania do wyboru from:

1) Uporządkuj swoje dokumenty najlepiej jak potrafisz i użyj modyfikatorów atomic najlepiej jak potrafisz, a dla pozostałego bitu użyj procesu w tle do czyszczenia rekordów, które mogą być zsynchronizowane. Na przykład usuwam elementy z inwentarza i dodaję je do tablicy reservedInventory tego samego dokumentu za pomocą modyfikatorów atomowych.

Dzięki temu zawsze Wiem, że przedmioty nie są dostępne w magazynie (ponieważ są zarezerwowane przez Klienta). Kiedy klient wymelduje się, ja wtedy usuń przedmioty z rezerwowanejinventory. Nie jest to standardowa transakcja, a ponieważ klient może porzucić koszyk, potrzebuję jakiegoś procesu w tle, aby przejść i znaleźć porzucone wózki i przenieść zarezerwowane zapasy z powrotem do dostępnej puli zapasów.

Jest to oczywiście mniej niż idealne rozwiązanie, ale jest to jedyna część dużej aplikacji, w której mongodb nie pasuje idealnie. Plus, do tej pory działa bez zarzutu. Może to nie być możliwe w wielu scenariuszach, ale ponieważ struktura dokumentu, którego używam, pasuje dobrze.

2) Użyj bazy transakcyjnej w połączeniu z MongoDB. Często używa się MySQL do dostarczania transakcji dla rzeczy, które ich absolutnie potrzebują, pozwalając MongoDB (lub innym NoSQL) robić to, co robi najlepiej.

Jeśli moje rozwiązanie z #1 nie działa na dłuższą metę, zbadam dalej połączenie MongoDB z MySQL, ale na razie #1 dobrze odpowiada moim potrzebom.

 137
Author: Bryan Migliorisi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-19 22:34:34

To nie jest poprawne, że MongoDB nie jest zgodny z kwasami. Wręcz przeciwnie, MongoDB jest Acid-compilant na poziomie dokumentu.

Każda aktualizacja do pojedynczego dokumentu to

  • atomowy: albo w pełni się uzupełnia, albo nie
  • spójny: żaden czytelnik nie zobaczy "częściowo zastosowanej" aktualizacji
  • odizolowany: ponownie, żaden czytelnik nie zobaczy "brudnego" odczytu
  • trwały: (z odpowiednim zapisem)

Jaki MongoDB nie ma is transakcje -- oznacza to, że aktualizacje wielu dokumentów, które można cofnąć i są zgodne z kwasami.

Zauważ, że możesz budować transakcje w oparciu o aktualizacje Zgodne z ACID do pojedynczego dokumentu, za pomocą przy użyciu dwufazowego commita.

 141
Author: William Z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 11:48:46

Dobre wyjaśnienie zawarte jest w "Starbucks nie używa dwufazowego Commita" .

Nie chodzi o bazy danych NoSQL, ale pokazuje, że czasami możesz sobie pozwolić na utratę transakcji lub tymczasową niespójność bazy danych.

Nie uznałbym tego za coś, co trzeba "naprawić". Poprawką jest użycie relacyjnej bazy danych zgodnej z kwasem. Wybierasz alternatywę NoSQL, gdy jej zachowanie odpowiada twojej aplikacji wymagania.

 34
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-22 16:07:32

Myślę, że inni już dali dobre odpowiedzi. Chciałbym jednak dodać, że istnieją Acid NOSQL DBs (jak http://ravendb.net / ). Więc nie jest to tylko decyzja NOSQL - no ACID vs Relational with ACID....

 16
Author: SubGate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 09:10:35

"nie zapisuje poprawnie" może oznaczać:

  1. Domyślnie MongoDB nie zapisuje zmian na dysku natychmiast. Istnieje więc możliwość, że powiesz użytkownikowi "aktualizacja się powiodła", nastąpi przerwa w zasilaniu i aktualizacja zostanie utracona. MongoDB udostępnia opcje kontroli poziomu "trwałości" aktualizacji. MoĹźe czekaÄ ‡ na otrzymanie aktualizacji przez inne repliki(w pamiÄ ™ ci), czekaÄ ‡ na zapis do lokalnego pliku dziennika, itd.

  2. Nie ma łatwego " atomic" aktualizacje wielu kolekcji, a nawet wielu dokumentów w tej samej kolekcji. W większości przypadków nie jest to problem, ponieważ można go obejść za pomocą dwufazowego Commita lub restrukturyzacji schematu tak, aby aktualizacje były dokonywane w jednym dokumencie. Zobacz to pytanie: bazy dokumentów: zbędne dane, referencje itp. (MongoDB)

 12
Author: Sergey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:07

Począwszy od MongoDB v4. 0, WIELODOKUMENTOWE transakcje ACID mają być obsługiwane. Dzięki izolacji migawek transakcje zapewnią globalnie spójny widok danych i wymuszą wykonanie "wszystko albo nic", aby zachować integralność danych.

Czują się jak transakcje ze świata relacyjnego, np.:

with client.start_session() as s:
    s.start_transaction()
    try:
        collection.insert_one(doc1, session=s)
        collection.insert_one(doc2, session=s)
        s.commit_transaction()
    except Exception:
        s.abort_transaction()

Zobacz https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb

 12
Author: Grigori Melnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-18 17:01:01

Aby lepiej zrozumieć, przeczytaj o właściwościach kwasu .

Również w dokumentacji MongoDB można znaleźć Pytanie i ODPOWIEDŹ .

MongoDB nie jest zgodny z kwasami. Przeczytaj poniżej, aby omówić kwas zgodność.
  1. MongoDB jest Atylko na poziomie dokumentu. Nie odpowiada definicji atomu, którą znamy z relacyjnych systemów bazodanowych, w szczególności linku powyżej. W tym sensie MongoDB nie jest zgodny z a z kwasu.
  2. MongoDB jest domyślnie Consitent. jednakże, możesz odczytywać z drugorzędnych serwerów w zestawie replik. W tym przypadku można tylko mieć ostateczną konsystencję. Jest to przydatne, jeśli nie masz nic przeciwko odczytaniu nieco nieaktualnych danych.
  3. MongoDB nie gwarantuje Isolacji (ponownie zgodnie z powyższą definicją):
  1. w przypadku systemów z wieloma współbieżnymi czytnikami i pisarzami, MongoDB będzie pozwalają klientom odczytać wyniki operacji zapisu przed write operation returns.
  2. Jeśli mongod zakończy się przed zatwierdzeniem dziennika, nawet jeśli zapis zwraca pomyślnie, zapytania mogą odczytywać dane, które nie będą istniały po ponownym uruchomieniu mongod.

Jednak, MongoDB modyfikuje każdy dokument w izolacji (dla wstawek i aktualizacje); tylko na poziomie dokumentu, a nie na transakcjach wielodokumentowych.

  1. w odniesieniu do Durabialność - możesz skonfigurować to zachowanie za pomocą opcji write concern, jednak nie jestem pewien. Może ktoś wie lepiej.

Uważam, że trwają badania nad przesunięciem NoSQL w kierunku ograniczeń kwasowych lub podobnych. Jest to wyzwanie, ponieważ bazy danych NoSQL są zwykle szybkie (er), a ograniczenia kwasowe mogą znacznie spowolnić wydajność.

 5
Author: Ely,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-09 04:56:55

Jedynym powodem, dla którego Atomic modyfikuje działanie przeciwko pojedynczej kolekcji, jest to, że deweloperzy mongodb wymienili ostatnio blokadę bazy danych z blokadą zapisu całej kolekcji. Decydując, że zwiększona współbieżność tutaj była warta kompromisu. W jego rdzeniu mongodb jest plikiem mapowanym w pamięci: przekazali zarządzanie pulą buforów podsystemowi maszyny wirtualnej. Ponieważ jest zawsze w pamięci, są w stanie uciec z bardzo oczywiście ziarnistych zamków: będziesz wykonywać tylko w pamięci operacje podczas trzymania go, co będzie niezwykle szybkie. Różni się to znacznie od tradycyjnego systemu bazodanowego, który jest czasami zmuszony do wykonywania operacji I / O podczas trzymania pagelocka lub rowlocka.

 4
Author: joeshmoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-16 22:35:12

"W MongoDB operacja na pojedynczym dokumencie jest atomowa" - to rzecz o przeszłości

W nowej wersji MongoDB 4.0 Można:

Jednak w sytuacjach wymagających atomiczności aktualizacji wielu dokumentów lub spójności odczytów do wielu dokumentów, MongoDB zapewnia możliwość wykonywania transakcji wielodokumentowych na zestawach replik. Transakcje wielodokumentowe mogą być wykorzystywane w wielu operacjach, kolekcjach, bazy danych i dokumenty. Transakcje wielodokumentowe zapewniają propozycję "wszystko albo nic". Po zatwierdzeniu transakcji wszystkie zmiany danych dokonane w transakcji są zapisywane. Jeśli jakakolwiek operacja w transakcji nie powiedzie się, transakcja zostanie przerwana, a wszystkie zmiany danych wprowadzone w transakcji zostaną odrzucone, nigdy nie staną się widoczne. Dopóki transakcja nie zostanie zatwierdzona, żadne operacje zapisu w transakcji nie są widoczne poza transakcją.

Choć jest kilka ograniczeń dla Jak i Jakie operacje można wykonać.

Sprawdź Mongo Doc. https://docs.mongodb.com/master/core/transactions/

 2
Author: Mysterious25K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-01 20:56:14

Możesz zaimplementować aktualizacje Atomic multi-key (transakcja serializowalna) po stronie klienta, jeśli twoja pamięć obsługuje liniowość według klucza oraz porównywanie i ustawianie (co jest prawdą w przypadku MongoDB). Takie podejście jest używane w Percolator Google i w CockroachDB , ale nic nie stoi na przeszkodzie, aby używać go z MongoDB.

Stworzyłem wizualizację krok po kroku takich transakcji. Mam nadzieję, że to pomoże Ci je zrozumieć.

If you ' re fine with Czytaj poziom committed isolation, a następnie warto przyjrzeć się transakcjom RAMPOWYM autorstwa Petera Bailisa. Mogą być również zaimplementowane dla MongoDB po stronie klienta.

 1
Author: rystsov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 02:34:06