Transaktionsisolierungsstufen in Neptune - Amazon Neptune

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Transaktionsisolierungsstufen in Neptune

Amazon Neptune implementiert unterschiedliche Transaktionsisolationsstufen für schreibgeschützte Abfragen und Mutationsabfragen. SPARQLund Gremlin-Abfragen werden auf der Grundlage der folgenden Kriterien als schreibgeschützt oder als Mutationsabfragen eingestuft:

  • In SPARQL gibt es einen klaren Unterschied zwischen Leseabfragen (SELECT, ASKCONSTRUCT, und DESCRIBE wie in der SPARQL1.1 Query Language-Spezifikation definiert) und Mutationsabfragen (INSERTund DELETE wie in der SPARQL1.1 Update-Spezifikation definiert).

    Beachten Sie, dass Neptune mehrere Mutationsabfragen, die zusammen gesendet werden (z. B. in einer POST-Nachricht, getrennt durch Semikolon), als eine einzige Transaktion behandelt. Sie sind gemeinsam entweder erfolgreich oder nicht erfolgreich. Wenn sie nicht erfolgreich sind, werden teilweise Änderungen zurückgesetzt.

  • In Gremlin klassifiziert Neptune eine Abfrage jedoch als schreibgeschützte Abfrage oder als Mutationsabfrage, abhängig davon, ob sie Abfragepfadschritte wie addE(), addV(), property() oder drop() enthält, die Daten manipulieren. Wenn die Abfrage einen solchen Pfadschritt enthält, wird sie als Mutationsabfrage klassifiziert und ausgeführt.

Es ist auch möglich, stehende Sitzungen in Gremlin zu verwenden. Weitere Informationen finden Sie unter Skriptbasierte Gremlin-Sitzungen. In diesen Sitzungen werden alle Abfragen (einschließlich schreibgeschützter Abfragen) mit derselben Isolierung wie Mutationsabfragen auf dem Writer-Endpunkt ausgeführt.

Bei Verwendung von Bolt-Lese-/Schreibsitzungen werden alle AbfragenopenCypher, einschließlich schreibgeschützter Abfragen, auf dem Writer-Endpunkt mit derselben Isolierung wie Mutationsabfragen ausgeführt.

Isolation schreibgeschützter Abfragen in Neptune

Neptune evaluiert schreibgeschützte Abfragen gemäß der Snapshot-Isolationssemantik. Das bedeutet, dass eine schreibgeschützte Abfrage logisch auf einem konsistenten Snapshot der Datenbank ausgeführt wird, wenn die Abfrageevaluierung beginnt. Neptune kann dann garantieren, dass keines der folgenden Phänomene eintritt:

  • Dirty reads – Schreibgeschützten Abfragen in Neptune werden niemals Daten ohne Commit aus einer gleichzeitigen Transaktion angezeigt.

  • Non-repeatable reads – Eine schreibgeschützte Transaktion, die dieselben Daten mehrmals liest, erhält stets dieselben Werte zurück.

  • Phantom reads – Eine schreibgeschützte Transaktion liest niemals Daten, die nach Beginn der Transaktion hinzugefügt wurden.

Da die Snapshot-Isolierung mithilfe von Multiversion Concurrency Control (MVCC) erreicht wird, müssen bei schreibgeschützten Abfragen keine Daten gesperrt werden und blockieren daher auch keine Mutationsabfragen.

Read Replicas akzeptieren nur schreibgeschützte Abfragen, sodass alle Abfragen für Read Replicas gemäß der SNAPSHOT-Isolationssemantik ausgeführt werden.

Der einzige zusätzliche Aspekt bei der Abfrage einer Read Replica besteht darin, dass es eine kleine Verzögerung bei der Replikation zwischen dem Writer und den Read Replicas geben kann. Dies bedeutet, dass eine Aktualisierung, die am Writer vorgenommen wurde, einige Zeit in Anspruch nehmen kann, bis sie auf die Read Replica übertragen wird, aus der Sie lesen. Die tatsächliche Replikationszeit ist von der Schreiblast der primären Instance abhängig. Die Neptune-Architektur unterstützt die Replikation mit niedriger Latenz, und die Replikationsverzögerung wird in einer Amazon-Metrik instrumentiert. CloudWatch

Aufgrund der SNAPSHOT-Isolationsstufe wird Leseabfragen stets ein konsistenter Zustand der Datenbank angezeigt, auch wenn es sich nicht um den neuesten Zustand handelt.

Wenn Sie eine starke Garantie benötigen, dass eine Abfrage das Ergebnis einer vorherigen Aktualisierung beachtet, senden Sie die Abfrage an den Writer-Endpunkt selbst und nicht an eine Read Replica.

Isolierung von Mutationsabfragen in Neptune

Als Teil von Mutationsabfragen erstellte Lesevorgänge werden unter READ COMMITTED-Transaktionsisolierung ausgeführt, was die Möglichkeit von fehlerhaften Lesevorgängen ausschließt. Abgesehen von den üblichen Garantien für die READ COMMITTED-Transaktionsisolierung bietet Neptune eine starke Garantie, dass weder PHANTOM- noch NON-REPEATABLE- Lesevorgänge erfolgen können.

Diese starken Garantien werden erreicht, indem Datensätze und Bereiche von Datensätzen beim Lesen von Daten gesperrt werden. Dadurch wird verhindert, dass gleichzeitige Transaktionen Einfügungen oder Löschungen in Indexbereichen vornehmen, nachdem sie gelesen wurden, was wiederholbare Lesevorgänge garantiert.

Anmerkung

Eine gleichzeitige Mutationstransaktion Tx2 könnte jedoch nach dem Start der Mutationstransaktion Tx1 beginnen und das Commit einer Änderung durchführen, bevor Tx1 Daten zum Lesen gesperrt hatte. In diesem Fall würde Tx1 die Änderung von Tx2 so sehen, als ob Tx2 sie vor dem Start von Tx1 abgeschlossen hätte. Da dies nur für Änderungen gilt, für die ein Commit durchgeführt wurde, kann ein dirty read nie auftreten.

Um den Sperrmechanismus zu verstehen, den Neptune für Mutationsabfragen verwendet, sollten zunächst die Details für das Diagrammdatenmodell und die Indizierungsstrategie in Neptune verstanden werden. Neptune verwaltet Daten mithilfe von drei Indizes, SPOG, POGS und GPSO.

Um wiederholbare Lesevorgänge für die READ COMMITTED-Transaktionsebene zu erzielen, nutzt Neptune Bereichssperren im verwendeten Index. Wenn beispielsweise eine Mutationsabfrage alle Eigenschaften und ausgehenden Grenzen eines Eckpunkts mit dem Namen person1 liest, würde der Knoten den gesamten durch das Präfix S=person1 im SPOG- Index definierten Bereich sperren, bevor die Daten gelesen werden.

Derselbe Mechanismus gilt bei der Verwendung anderer Indizes. Wenn beispielsweise eine Mutationstransaktion alle Quell-Ziel-Eckpunktpaare für eine bestimmte Grenzbezeichnung mit dem POGS-Index absucht, wäre der Bereich für die Grenzbezeichnung in der P-Position gesperrt. Jede gleichzeitige Transaktion, unabhängig davon, ob es sich um eine schreibgeschützte oder eine Mutationsabfrage handelt, könnte dennoch Lesevorgänge innerhalb des gesperrten Bereichs durchführen. Jede Mutation, die das Einfügen oder Löschen neuer Datensätze im gesperrten Präfixbereich beinhaltet, erfordert jedoch eine exklusive Sperre und würde verhindert werden.

Anders gesagt: Wenn ein Bereich des Indexes von einer Mutationstransaktion gelesen wurde, gibt es eine starke Garantie, dass dieser Bereich bis zum Ende der Lesetransaktion nicht durch gleichzeitige Transaktionen geändert wird. Auf diese Weise wird sichergestellt, dass kein non-repeatable reads auftritt.

Konfliktlösung mithilfe von Sperrwartezeitüberschreitungen

Wenn eine zweite Transaktion versucht, einen Datensatz in einem Bereich zu ändern, den eine erste Transaktion gesperrt hat, erkennt Neptune den Konflikt sofort und blockiert die zweite Transaktion.

Wenn keine Abhängigkeitssperre erkannt wird, wendet Neptune automatisch eine Sperrwartezeitüberschreitung an, bei dem die blockierte Transaktion bis zu 60 Sekunden wartet, bis die sperrende Transaktion abgeschlossen ist und die Sperre aufgehoben wurde.

  • Wenn die Sperrwartezeit abläuft, bevor die Sperre aufgehoben wird, wird die blockierte Transaktion rückabgewickelt.

  • Wenn die Sperre innerhalb des Sperrwartezeitraums aufgehoben wird, wird die zweite Transaktion entsperrt und kann erfolgreich abgeschlossen werden, ohne dass ein erneuter Versuch erfolgen muss.

Wenn Neptune jedoch eine Abhängigkeitssperre zwischen den beiden Transaktionen erkennt, ist eine automatische Beseitigung des Konflikts nicht möglich. In diesem Fall bricht Neptune eine der beiden Transaktionen sofort ab und führt ein Rollback für diese Transaktion aus, ohne eine Sperrwartezeitüberschreitung zu initiieren. Neptune versucht dabei, die Transaktion rückgängig zu machen, in der die wenigsten Datensätze eingefügt oder gelöscht wurden.

Bereichssperren und falsche Konflikte

Neptune führt Bereichssperren mithilfe von Gap-Sperren aus. Eine Gap-Sperre ist eine Sperre für eine Lücke zwischen Indexdatensätzen oder eine Sperre für eine Lücke vor dem ersten oder nach dem letzten Indexdatensatz.

Neptune verwendet eine sogenannte Verzeichnistabelle, um bestimmten Zeichenkettenliteralen numerische ID-Werte zuzuordnen. Dies ist ein Beispielstatus eines solchen Neptun-Verzeichnisses: Tabelle:

String ID

Typ

1

default_graph

2

person_3

3

person_1

5

knows

6

person_2

7

age

8

edge_1

9

lives_in

10

New York

11

Person

12

Place

13

edge_2

14

Die obigen Zeichenketten gehören zu einem Eigenschaftsgraphenmodell, aber die Konzepte gelten auch für alle Graphmodelle gleichermaßen. RDF

Der entsprechende Status des Index SPOG (Subject-Predicate-Object_Graph) ist unten links dargestellt. Rechts werden die entsprechenden Zeichenfolgen gezeigt, um die Bedeutung der Indexdaten zu vermitteln.

S (ID) P (ID) O (ID) G (ID) S (Zeichenfolge) P (Zeichenfolge) O (Zeichenfolge) G (Zeichenfolge)

3

1

12

2

person_3

Typ

Person

default_graph

5

1

12

2

person_1

Typ

Person

default_graph

5

6

3

9

person_1

knows

person_3

edge_1

5

8

40

2

person_1

age

40

default_graph

5

10

11

14

person_1

lives_in

New York

edge_2

7

1

12

2

person_2

Typ

Person

default_graph

11

1

13

2

New York

Typ

Place

default_graph

Wenn nun eine Mutationsabfrage alle Eigenschaften und ausgehenden Kanten eines genannten Scheitelpunkts liestperson_1, würde der Knoten vor dem Lesen der Daten den gesamten durch das Präfix S=person_1 im Index definierten Bereich sperren. SPOG Die Bereichssperre würde Gap-Sperren für alle übereinstimmenden Datensätze und den ersten Datensatz einrichten, der nicht übereinstimmt. Übereinstimmende Datensätze würden gesperrt. Nicht übereinstimmende Datensätze würden nicht gesperrt. Neptune würde die Gap-Sperren wie folgt platzieren:

  • 5 1 12 2 (Lücke 1)

  • 5 6 3 9 (Lücke 2)

  • 5 8 40 2 (Lücke 3)

  • 5 10 11 14 (Lücke 4)

  • 7 1 12 2 (Lücke 5)

Dies sperrt die folgenden Datensätze:

  • 5 1 12 2

  • 5 6 3 9

  • 5 8 40 2

  • 5 10 11 14

In diesem Zustand werden die folgenden Operationen berechtigterweise blockiert:

  • Einfügen einer neuen Eigenschaft oder Kante für S=person_1. Eine neue Eigenschaft, die sich von type unterscheidet, oder eine neue Kante müsste in Lücke 2, Lücke 3, Lücke 4 oder Lücke 5 eingefügt werden, die alle gesperrt sind.

  • Löschen eines der vorhandenen Datensätze.

Gleichzeitig würden einige gleichzeitige Operationen fälschlicherweise blockiert (was zu falschen Konflikten führen würde):

  • Alle Eigenschaften oder Kanteneinfügungen für S=person_3 werden blockiert, da sie in Lücke 1 platziert werden müssten.

  • Jede neue Eckpunkteinfügung, der eine ID zwischen 3 und 5 zugewiesen wird, würde blockiert, da sie in Lücke 1 eingefügt werden müsste.

  • Jede neue Eckpunkteinfügung, der eine ID zwischen 5 und 7 zugewiesen wird, würde blockiert, da sie in Lücke 5 eingefügt werden müsste.

Gap-Sperren sind nicht präzise genug, um die Lücke für ein einzelnes bestimmtes Prädikat zu sperren (um z. B. Lücke 5 für Prädikat S=5 zu sperren).

Die Bereichssperren werden nur in dem Index platziert, in dem der Lesevorgang stattfindet. Im obigen Fall sind Datensätze nur im SPOG Index gesperrt, nicht in POGS oderGPSO. Lesevorgänge für eine Abfrage können abhängig von den Zugriffsmustern, die mit dem explain APIs (für Sparql und für Gremlin) aufgelistet werden können, für alle Indizes durchgeführt werden.

Anmerkung

Gap-Sperren können auch als sichere gleichzeitige Aktualisierungen der zugrunde liegenden Indizes verstanden werden, was ebenfalls zu falschen Konflikten führen kann. Diese Gap-Sperren werden unabhängig von der Isolationsstufe oder den von der Transaktion ausgeführten Lesevorgängen platziert.

Falsche Konflikte können nicht nur auftreten, wenn gleichzeitige Transaktionen aufgrund von Lückensperren kollidieren, sondern in einigen Fällen auch, wenn eine Transaktion nach einem Fehler erneut versucht wird. Wenn das durch den Fehler ausgelöste Rollback noch nicht abgeschlossen ist und die Sperren, die zuvor auf die Transaktion angewendet wurden, noch nicht vollständig aufgehoben wurden, stößt der erneute Versuch auf einen falschen Konflikt und schlägt fehl.

Bei hoher Auslastung stellen Sie in der Regel fest, dass 3 bis 4 % der Schreibabfragen aufgrund falscher Konflikte fehlschlagen. Für einen externen Client sind diese falschen Konflikte schwer vorherzusagen und sollten mithilfe von Wiederholungsversuchen behandelt werden.