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
,ASK
CONSTRUCT
, undDESCRIBE
wie in der SPARQL1.1 Query Language-Spezifikationdefiniert) und Mutationsabfragen ( INSERT
undDELETE
wie in der SPARQL1.1Update-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()
oderdrop()
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.
Themen
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 vontype
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.