it-swarm.com.de

Was bedeutete es wirklich, dass MongoDB vor Version 4 nicht mit ACID kompatibel war?

Ich bin kein Datenbankexperte und habe keinen formalen Informatikhintergrund. Ich möchte wissen, welche Arten von negativen Dingen in der realen Welt auftreten können, wenn Sie eine alte MongoDB-Version vor v4 verwenden. die nicht ACID konform waren. Dies gilt für alle nicht mit ACID kompatiblen Datenbanken.

Ich verstehe, dass MongoDB Atomic Operations ausführen kann, aber dass es "keine herkömmlichen Sperren und komplexen Transaktionen unterstützt", hauptsächlich aus Gründen der Leistung. Ich verstehe auch die Bedeutung von Datenbanktransaktionen und das Beispiel, wenn Ihre Datenbank für eine Bank bestimmt ist und Sie mehrere Datensätze aktualisieren, die alle synchron sein müssen. Sie möchten, dass die Transaktion in den Ausgangszustand zurückgesetzt wird, wenn eine vorhanden ist Stromausfall, damit Guthaben gleich Kauf usw. ist.

Aber wenn ich mich über MongoDB unterhalte, werfen diejenigen von uns, die die technischen Details der tatsächlichen Implementierung von Datenbanken nicht kennen, Aussagen wie:

MongoDB ist viel schneller als MySQL und Postgres, aber es gibt eine winzige Chance, wie 1 in einer Million, dass es "nicht richtig speichert".

Dieser Teil, der nicht korrekt gespeichert werden kann, bezieht sich auf dieses Verständnis: Wenn zum Zeitpunkt des Schreibens an MongoDB ein Stromausfall vorliegt, besteht für einen bestimmten Datensatz die Möglichkeit, dass Sie Seitenzugriffe in Dokumenten mit 10 Attributen nachverfolgen jeweils), dass eines der Dokumente nur 5 der Attribute gespeichert hat… was bedeutet, dass Ihre Seitenzähler im Laufe der Zeit "leicht" ausfallen werden. Sie werden nie wissen, um wie viel, Sie wissen, dass sie zu 99,999% korrekt sind, aber nicht zu 100%. Dies liegt daran, dass es nicht garantiert ist, dass die Operation atomar war, es sei denn, Sie haben dies ausdrücklich als mongodb atomic operation definiert.

Meine Frage ist also, was ist die richtige Interpretation von wann und warum MongoDB möglicherweise nicht "richtig speichern" kann? Welche Teile von ACID werden unter welchen Umständen nicht erfüllt und woher wissen Sie, wann 0,001% Ihrer Daten deaktiviert sind? Kann das nicht irgendwie behoben werden? Wenn nicht, bedeutet dies, dass Sie Dinge wie Ihre users -Tabelle nicht in MongoDB speichern sollten, da ein Datensatz möglicherweise nicht gespeichert wird. Aber andererseits muss dieser 1/1,000,000-Benutzer möglicherweise nur "versuchen, sich erneut anzumelden", nein?

Ich bin nur auf der Suche nach einer Liste, wann/warum negative Dinge mit einer ACID-nicht-kompatiblen Datenbank wie MongoDB passieren, und im Idealfall, wenn es eine Standard-Problemumgehung gibt (wie Ausführen eines Hintergrundjobs zum Bereinigen von Daten oder Verwenden von SQL für diese usw.). .

220
Lance Pollard

Eine Sache, die Sie mit MongoDB verlieren, sind Transaktionen mit mehreren Sammlungen (Tabellen). Atomic-Modifikatoren in MongoDB können nur für ein einzelnes Dokument verwendet werden.

Wenn Sie einen Artikel aus dem Inventar entfernen und gleichzeitig zu einer Bestellung hinzufügen müssen, können Sie dies nicht. Es sei denn, diese beiden Dinge - Inventar und Bestellungen - befinden sich im selben Dokument (was sie wahrscheinlich nicht tun).

Ich bin auf dasselbe Problem in einer Anwendung gestoßen, an der ich arbeite, und hatte zwei mögliche Lösungen zur Auswahl:

1) Strukturieren Sie Ihre Dokumente so gut Sie können und verwenden Sie atomare Modifikatoren so gut Sie können. Verwenden Sie für das verbleibende Bit einen Hintergrundprozess, um Datensätze zu bereinigen, die möglicherweise nicht synchron sind. Zum Beispiel entferne ich Elemente aus dem Inventar und füge sie mit atomaren Modifikatoren zu einem reservedInventory-Array desselben Dokuments hinzu.

Auf diese Weise weiß ich immer, dass Artikel NICHT im Inventar verfügbar sind (da sie von einem Kunden reserviert wurden). Wenn der Kunde auscheckt, entferne ich die Artikel aus dem reservierten Bestand. Es handelt sich nicht um eine Standardtransaktion, und da der Kunde den Einkaufswagen aufgeben könnte, benötige ich einen Hintergrundprozess, um aufgegebene Einkaufswagen zu finden und das reservierte Inventar zurück in den verfügbaren Inventarpool zu verschieben.

Dies ist offensichtlich weniger als ideal, aber es ist der einzige Teil einer großen Anwendung, bei der Mongodb nicht perfekt zu den Anforderungen passt. Plus, es funktioniert soweit einwandfrei. Für viele Szenarien ist dies möglicherweise nicht möglich, aber aufgrund der von mir verwendeten Dokumentstruktur passt es gut.

2) Verwenden Sie eine Transaktionsdatenbank in Verbindung mit MongoDB. Es ist üblich, MySQL zu verwenden, um Transaktionen für die Dinge bereitzustellen, die sie unbedingt benötigen, während MongoDB (oder jedes andere NoSQL) das tut, was es am besten kann.

Wenn meine Lösung von Nummer 1 auf lange Sicht nicht funktioniert, werde ich die Kombination von MongoDB mit MySQL weiter untersuchen, aber momentan entspricht Nummer 1 meinen Anforderungen.

129

Es ist eigentlich nicht richtig, dass MongoDB nicht ACID-konform ist. Im Gegenteil, MongoDB ist ACID-kompilierbar auf Dokumentebene.

Jede Aktualisierung eines einzelnen Dokuments ist

  • Atomic: Es ist entweder vollständig oder nicht vollständig
  • Konsistent: Kein Leser sieht ein "teilweise angewendetes" Update
  • Isoliert: Wieder wird kein Leser einen "schmutzigen" Lesevorgang sehen
  • Haltbar: (mit dem entsprechenden Schreiben Bedenken)

Was MongoDB nicht hat, sind Transaktionen - dh Aktualisierungen für mehrere Dokumente, die rückgängig gemacht werden können und sind ACID-konform.

Beachten Sie, dass Sie Transaktionen auf den ACID-kompatiblen Aktualisierungen eines einzelnen Dokuments aufbauen können, indem Sie mit zweiphasigem Festschreiben .

131
William Z

Eine gute Erklärung finden Sie in "Starbucks verwendet kein Zwei-Phasen-Commit" .

Es geht nicht um NoSQL-Datenbanken, aber es zeigt, dass Sie es sich manchmal leisten können, eine Transaktion zu verlieren oder Ihre Datenbank vorübergehend in einem inkonsistenten Zustand zu halten.

Ich würde es nicht als etwas betrachten, das "repariert" werden muss. Das Update besteht darin, eine ACID-kompatible relationale Datenbank zu verwenden. Sie wählen eine NoSQL-Alternative, wenn ihr Verhalten Ihren Anwendungsanforderungen entspricht.

34
duffymo

Ich denke, andere Leute haben bereits gute Antworten gegeben. Allerdings möchte ich hinzufügen, dass es ACID NOSQL DBs gibt (wie http://ravendb.net/ ). Es ist also nicht nur Entscheidung NOSQL - keine ACID vs Relational mit ACID ....

16
SubGate

"Nicht korrekt speichern" könnte bedeuten:

  1. Standardmäßig speichert MongoDB Ihre Änderungen nicht sofort auf dem Laufwerk. Es besteht also die Möglichkeit, dass Sie einem Benutzer mitteilen, dass das Update erfolgreich ist, ein Stromausfall auftritt und das Update verloren geht. MongoDB bietet Optionen zur Steuerung der Aktualisierungsdauer. Es kann warten, bis die anderen Replikate dieses Update erhalten (im Speicher), bis das Schreiben in die lokale Journaldatei erfolgt usw.

  2. Es gibt keine einfachen "atomaren" Aktualisierungen für mehrere Sammlungen und sogar für mehrere Dokumente in derselben Sammlung. In den meisten Fällen ist dies kein Problem, da es mit Two Phase Commit umgangen oder das Schema so umstrukturiert werden kann, dass Aktualisierungen an einem einzelnen Dokument vorgenommen werden. Siehe diese Frage: Dokumentendatenbanken: Redundante Daten, Referenzen usw. (speziell MongoDB)

12
Sergey

Ab MongoDB v4.0 sollen ACID-Transaktionen mit mehreren Dokumenten unterstützt werden. Durch die Snapshot-Isolation bieten Transaktionen eine global konsistente Sicht auf Daten und erzwingen die vollständige oder vollständige Ausführung, um die Datenintegrität zu gewährleisten.

Sie fühlen sich wie Transaktionen aus der relationalen Welt, z.

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()

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

9
Grigori Melnik

Bitte lesen Sie die ACID-Eigenschaften , um ein besseres Verständnis zu erhalten.

Auch in der MongoDB-Dokumentation finden Sie ein Frage und Antwort .

MongoDB ist nicht ACID-konform. Lesen Sie weiter unten, um eine Erläuterung der ACID-Konformität zu erhalten.

  1. MongoDB ist nur auf Dokumentebene Atomic. Es entspricht nicht der Definition von atomar, die wir aus relationalen Datenbanksystemen kennen, insbesondere dem obigen Link. In diesem Sinne entspricht MongoDB nicht dem A von ACID.
  2. MongoDB ist standardmäßig Consitent. Sie können jedoch von sekundären Servern in einem Replikatsatz lesen. In diesem Fall können Sie nur eine eventuelle Konsistenz haben. Dies ist nützlich, wenn es Ihnen nichts ausmacht, leicht veraltete Daten zu lesen.
  3. MongoDB übernimmt keine Garantie für Isolation (ebenfalls gemäß obiger Definition):
  1. Bei Systemen mit mehreren gleichzeitigen Lese- und Schreibvorgängen können Clients mit MongoDB die Ergebnisse eines Schreibvorgangs lesen, bevor der Schreibvorgang zurückgegeben wird.
  2. Wenn der Mongod vor dem Festschreiben des Journals beendet wird, haben Abfragen möglicherweise Lesedaten, die nach dem Neustart des Mongod nicht mehr vorhanden sind, selbst wenn ein Schreibvorgang erfolgreich abgeschlossen wurde.

MongoDB ändert jedoch jedes Dokument einzeln (für Einfügungen und Aktualisierungen). Nur auf Dokumentebene, nicht bei Transaktionen mit mehreren Dokumenten.

  1. In Bezug auf Durability - Sie können dieses Verhalten mit der Option write concern Konfigurieren, sind sich jedoch nicht sicher. Vielleicht weiß es jemand besser.

Ich glaube, einige Forschungen sind im Gange, um NoSQL in Richtung von ACID-Einschränkungen oder ähnlichem zu bewegen. Dies ist eine Herausforderung, da NoSQL-Datenbanken normalerweise schnell sind und ACID-Einschränkungen die Leistung erheblich beeinträchtigen können.

4
Ely

Der einzige Grund, warum Atomic die Arbeit an einer einzelnen Sammlung ändert, ist, dass die Mongodb-Entwickler kürzlich eine Datenbanksperre durch eine sammlungsweite Schreibsperre ausgetauscht haben. Die Entscheidung, dass die erhöhte Nebenläufigkeit hier den Kompromiss wert war. Mongodb ist im Kern eine Datei mit Speicherzuordnung: Sie haben die Verwaltung des Pufferpools an das VM-Subsystem des Computers delegiert. Da es sich immer im Speicher befindet, können sie mit sehr detaillierten Sperren davonkommen: Sie führen nur speicherinterne Vorgänge aus, während Sie diese gedrückt halten, was extrem schnell ist. Dies unterscheidet sich erheblich von einem herkömmlichen Datenbanksystem, das manchmal gezwungen ist, E/A-Vorgänge auszuführen, während es ein Pagelock oder ein Rowlock hält.

4
joeshmoe

"In MongoDB ist eine Operation an einem einzelnen Dokument atomar" - Das ist die Sache der Vergangenheit

In der neuen Version von MongoDB 4.0 KÖNNEN Sie:

In Situationen, in denen für die Aktualisierung mehrerer Dokumente oder die Konsistenz zwischen den Lesevorgängen mehrerer Dokumente eine Unterscheidung erforderlich ist, bietet MongoDB die Möglichkeit, Transaktionen mit mehreren Dokumenten für Replikatsätze durchzuführen. Transaktionen mit mehreren Dokumenten können für mehrere Vorgänge, Sammlungen, Datenbanken und Dokumente verwendet werden. Transaktionen mit mehreren Dokumenten bieten ein "Alles-oder-Nichts" -Angebot. Wenn eine Transaktion festgeschrieben wird, werden alle in der Transaktion vorgenommenen Datenänderungen gespeichert. Wenn ein Vorgang in der Transaktion fehlschlägt, wird die Transaktion abgebrochen und alle in der Transaktion vorgenommenen Datenänderungen werden verworfen, ohne dass sie jemals sichtbar werden. Bis zum Festschreiben einer Transaktion sind außerhalb der Transaktion keine Schreibvorgänge in der Transaktion sichtbar.

Es gibt jedoch nur wenige Einschränkungen für Wie und Was Vorgänge, die ausgeführt werden können.

Überprüfen Sie den Mongo Doc. https://docs.mongodb.com/master/core/transactions/

2
Mysterious25K

Sie können clientseitig atomare Multi-Key-Updates (serialisierbare Transaktionen) implementieren, wenn Ihr Speicher die Linearisierbarkeit und das Vergleichen und Festlegen von Schlüsseln unterstützt (dies gilt für MongoDB). Dieser Ansatz wird in Googles Percolator und in CockroachDB verwendet, aber nichts hindert Sie daran, ihn mit MongoDB zu verwenden.

Ich habe eine schrittweise Visualisierung solcher Transaktionen erstellt. Ich hoffe, es wird Ihnen helfen, sie zu verstehen.

Wenn Sie die festgeschriebene Isolationsstufe für das Lesen in Ordnung haben, ist es sinnvoll, sich RAMP-Transaktionen von Peter Bailis anzusehen. Sie können auch clientseitig für MongoDB implementiert werden.

1
rystsov