MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Bis zu welcher Ebene sperrt MongoDB Schreibvorgänge? (oder:was bedeutet das pro Verbindung

MongoDB-Sperren ist anders

Das Sperren in MongoDB funktioniert nicht wie das Sperren in einem RDBMS, daher ist eine kurze Erklärung angebracht. In früheren Versionen von MongoDB gab es einen einzigen globalen Reader/Writer-Latch. Beginnend mit MongoDB 2.2 gibt es einen Lese-/Schreib-Latch für jede Datenbank.

Die Leser-Schreiber-Verriegelung

Der Latch ist ein Multiple-Reader, ein Single-Writer und ein Writer-greedy. Das bedeutet:

  • Es kann eine unbegrenzte Anzahl gleichzeitiger Leser in einer Datenbank geben
  • Es kann jeweils nur ein Autor für jede Sammlung in einer Datenbank vorhanden sein (mehr dazu später)
  • Schreiber blockieren Leser
  • Mit "schreibgierig" meine ich, dass sobald eine Schreibanforderung eingeht, alle Leser blockiert werden, bis der Schreibvorgang abgeschlossen ist (dazu später mehr)

Beachten Sie, dass ich dies eher als "Latch" als als "Lock" bezeichne. Dies liegt daran, dass es leicht ist und in einem richtig entworfenen Schema die Schreibsperre in der Größenordnung von etwa einem Dutzend Mikrosekunden gehalten wird. Sehen Sie hier für mehr über Leser-Schreiber-Sperren.

In MongoDB können Sie beliebig viele gleichzeitige Abfragen ausführen:Solange sich die relevanten Daten im RAM befinden, werden sie alle ohne Sperrkonflikte erfüllt.

Atomic Document Updates

Denken Sie daran, dass die Transaktionsebene in MongoDB ein einzelnes Dokument ist. Alle Aktualisierungen eines einzelnen Dokuments sind atomar. MongoDB erreicht dies, indem es den Write-Latch nur so lange hält, wie es dauert, um ein einzelnes Dokument im RAM zu aktualisieren. Wenn es eine langsam laufende Operation gibt (insbesondere wenn ein Dokument oder ein Indexeintrag von der Festplatte ausgelagert werden muss), dann wird diese Operation nachgeben das Write-Latch. Wenn die Operation den Latch ergibt, kann die nächste Operation in der Warteschlange fortgesetzt werden.

Dies bedeutet, dass die Schreibvorgänge in alle Dokumente innerhalb einer einzigen Datenbank serialisiert werden. Dies kann ein Problem sein, wenn Sie ein schlechtes Schemadesign haben und Ihre Schreibvorgänge lange dauern, aber in einem richtig entworfenen Schema ist das Sperren kein Problem.

Schreibgierig

Noch ein paar Worte zur Schreibgier:

Nur ein Schreiber kann gleichzeitig den Riegel halten; mehrere Leser können den Riegel gleichzeitig halten. In einer naiven Implementierung könnten Autoren auf unbestimmte Zeit verhungern, wenn nur ein einziger Reader in Betrieb wäre. Um dies zu vermeiden, stellt in der MongoDB-Implementierung ein einzelner Thread eine Schreibanforderung für einen bestimmten Latch

  • Alle nachfolgenden Leser, die diesen Latch benötigen, werden blockiert
  • Dieser Autor wird warten, bis alle aktuellen Reader fertig sind
  • Der Writer ruft den Write-Latch ab, führt seine Arbeit aus und gibt dann den Write-Latch frei
  • Alle Leser in der Warteschlange werden nun fortfahren

Das tatsächliche Verhalten ist komplex, da dieses schreibgierige Verhalten mit dem Nachgeben auf eine Weise interagiert, die nicht offensichtlich sein kann. Denken Sie daran, dass es ab Version 2.2 eine separate gibt Latch für jede Datenbank, sodass Schreibvorgänge in eine beliebige Sammlung in Datenbank „A“ einen separaten Latch erhalten als Schreibvorgänge in eine beliebige Sammlung in Datenbank „B“.

Spezielle Fragen

Zu den konkreten Fragen:

  • Sperren (eigentlich Latches) werden vom MongoDB-Kernel nur so lange gehalten, wie es dauert, ein einzelnes Dokument zu aktualisieren
  • Wenn Sie mehrere Verbindungen zu MongoDB haben und jede davon eine Reihe von Schreibvorgängen durchführt, wird der Latch pro Datenbank nur so lange gehalten, wie es dauert, bis dieser Schreibvorgang abgeschlossen ist
  • Mehrere Verbindungen, die zum Ausführen von Schreibvorgängen (Aktualisieren/Einfügen/Löschen) eingehen, werden alle verschachtelt

Während dies so klingt, als wäre es ein großes Leistungsproblem, verlangsamt es die Dinge in der Praxis nicht. Mit einem richtig entworfenen Schema und einer typischen Arbeitslast sättigt MongoDB die Festplatten-E/A-Kapazität – selbst für eine SSD – bevor der Sperrprozentsatz für eine Datenbank über 50 % steigt.

Der mir bekannte MongoDB-Cluster mit der höchsten Kapazität führt derzeit 2 Millionen Schreibvorgänge pro Sekunde aus.