DAX- und DynamoDB-Konsistenzmodelle - Amazon-DynamoDB

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.

DAX- und DynamoDB-Konsistenzmodelle

Amazon DynamoDB Accelerator (DAX) ist ein Write-Through-Cache-Service, der das Hinzufügen eines Caches zu DynamoDB-Tabellen vereinfachen soll. Da DAX getrennt von DynamoDB arbeitet, ist es wichtig, dass Sie die Konsistenzmodelle von DAX und DynamoDB verstehen, um sicherzustellen, dass sich Ihre Anwendungen wie erwartet verhalten.

In vielen Anwendungsfällen wirkt sich die Art und Weise, wie Ihre Anwendung verwendet, auf die Konsistenz der Daten im DAX-Cluster sowie auf die Konsistenz der Daten zwischen DAX und DynamoDB aus.

Konsistenz zwischen DAX-Cluster-Knoten

Um eine hohe Verfügbarkeit für Ihre Anwendung zu erreichen, empfehlen wir, dass Sie mindestens drei Knoten für Ihren DAX-Cluster bereitstellen. Platzieren Sie diese Knoten dann in mehrere Availability Zones einer Region.

Wenn Ihr DAX-Cluster ausgeführt wird, repliziert er die Daten zwischen allen Knoten im Cluster (unter der Annahme, dass Sie mehr als einen Knoten bereitgestellt haben). Erwägen Sie eine Anwendung, die eine erfolgreiche UpdateItem-Operation mit DAX ausführt. Mit dieser Aktion wird der Element-Cache im primären Knoten mit dem neuen Wert geändert. Dieser Wert wird dann auf alle anderen Knoten im Cluster repliziert. Diese Replikation ist ein Eventually Consistent-Vorgang und dauert in der Regel weniger als eine Sekunde.

In diesem Szenario ist es möglich, dass zwei Clients denselben Schlüssel aus demselben DAX-Cluster lesen, jedoch abhängig von dem Knoten, auf den jeder Client zugegriffen hat, verschiedene Werte erhalten. Die Knoten sind alle konsistent, wenn die Aktualisierung vollständig auf alle Knoten im Cluster repliziert wurde. (Dieses Verhalten ähnelt dem Eventually-Consistent-Verhalten von DynamoDB.)

Wenn Sie eine Anwendung erstellen, die DAX verwendet, sollten Sie diese so konzipieren, dass sie Eventually-Consistent-Daten tolerieren kann.

Verhalten des DAX-Element-Caches

Jeder DAX-Cluster hat zwei getrennte Caches – einen Element- und einen Abfrage-Cache. Weitere Informationen finden Sie unter DAX: So funktioniert es.

In diesem Abschnitt werden die Konsistenzimplikationen für das Lesen aus dem und Schreiben in den DAX-Element-Cache beschrieben.

Konsistente Lesezugriffe

Mit DynamoDB führt die GetItem-Operation standardmäßig einen Eventually-Consistent-Lesevorgang aus. Angenommen, Sie verwenden UpdateItem mit dem DynamoDB-Client. Wenn Sie versuchen, dasselbe Element anschließend sofort zu lesen, kann es sein, dass die Daten so wie vor der Aktualisierung erscheinen. Der Grund hierfür ist die Verzögerung bei der Verbreitung auf alle DynamoDB-Speicherorte. Die Konsistenz wird in der Regel innerhalb von Sekunden erzielt. Wenn Sie den Lesevorgang erneut versuchen, sehen Sie wahrscheinlich das aktualisierte Element.

Wenn Sie GetItem mit dem DAX-Client verwenden, erfolgt die Operation (in diesem Fall ein Eventually-Consistent-Lesevorgang) wie folgt:

Workflow-Diagramm mit den nummerierten Schritten zum Aktualisieren eines Elements.
  1. Der DAX-Client erstellt eine GetItem-Anforderung. DAX versucht, das angeforderte Element aus dem Element-Cache zu lesen. Wenn sich das Element im Cache befindet (Cache-Treffer) gibt DAX es an die Anwendung zurück.

  2. Wenn das Element nicht verfügbar ist (Cache-Fehler), führt DAX eine GetItem-Operation für DynamoDB aus.

  3. DynamoDB gibt das angeforderte Element zurück und DAX speichert es im Element-Cache.

  4. DAX gibt das Element an die Anwendung zurück.

  5. (nicht dargestellt) Wenn der DAX-Cluster mehr als einen Knoten enthält, wird das Element auf alle anderen Knoten im Cluster repliziert.

Das Element bleibt im Element-Cache von DAX, abhängig von der (TTL)-Einstellung und vom LRU-Algorithmus des Caches. Weitere Informationen finden Sie unter DAX: So funktioniert es.

Während dieses Zeitraums liest DAX das Element nicht erneut aus DynamoDB. Wenn das Element von einem anderen Benutzer mit einem DynamoDB-Client unter Umgehung von DAX aktualisiert wird, liefert eine GetItem-Anforderung, die den DAX-Client verwendet, andere Ergebnisse als eine GetItem-Anforderung, die den DynamoDB-Client verwendet. In diesem Szenario enthalten DAX und DynamoDB inkonsistente Werte für denselben Schlüssel, bis die TTL für das DAX-Element abgelaufen ist.

Wenn eine Anwendung Daten in einer zugrunde liegenden DynamoDB-Tabelle unter Umgehung von DAX ändert, muss die Anwendung etwaige Dateninkonsistenzen vorhersehen und tolerieren.

Anmerkung

Neben GetItem unterstützt der DAX-Client auch BatchGetItem-Anforderungen. BatchGetItem ist in erster Linie ein Wrapper für einzelne oder mehrere GetItem-Anforderungen, sodass DAX diese als individuelle GetItem-Operationen behandelt.

Konsistente Schreibzugriffe

DAX ist ein Write-Through-Cache-Service, der die Konsistenz des DAX-Element-Caches mit den zugrunde liegenden DynamoDB-Tabellen vereinfachen soll.

Der DAX-Client unterstützt dieselben API-Operationen wie DynamoDB (PutItem, UpdateItem, DeleteItem, BatchWriteItem und TransactWriteItems). Wenn Sie diese Operationen mit dem DAX-Client verwenden, werden die Elemente sowohl in DAX als auch DynamoDB geändert. DAX aktualisiert die Elemente in seinem Element-Cache, und zwar unabhängig vom TTL-Wert für diese Elemente.

Beispiel: Sie erstellen eine GetItem-Anforderung vom DAX-Client zum Lesen eines Elements in der ProductCatalog Tabelle. (Der Partitionsschlüssel ist Id. Ein Sortierschlüssel ist nicht vorhanden.) Sie rufen das Element mit der Id 101 ab. Der QuantityOnHand-Wert für dieses Element ist 42. DAX speichert das Element im Element-Cache mit einem bestimmten TTL-Format. In diesem Beispiel ist der TTL-Wert zehn Minuten. Drei Minuten später verwendet eine andere Anwendung den DAX-Client, um dasselbe Element zu aktualisieren, sodass der QuantityOnHand-Wert jetzt 41 lautet. Vorausgesetzt, das Element wird nicht erneut aktualisiert, geben alle nachfolgenden Lesevorgänge für dasselbe Element während der nächsten zehn Minuten den im Cache gespeicherten Wert für QuantityOnHand (41) zurück.

Wie DAX Schreibzugriffe verarbeitet

DAX ist für Anwendungen konzipiert, die Lesevorgänge mit hoher Leistung erfordern. Als Write-Through-Cache übergibt DAX Ihre Schreibvorgänge synchron an DynamoDB und repliziert dann automatisch und asynchron resultierende Aktualisierungen in den Elementcache über alle Knoten im Cluster. Sie brauchen keine Cache-Invalidierungslogik verwalten, da DAX diesen Vorgang für Sie übernimmt.

DAX unterstützt die folgenden Schreibvorgänge: PutItem, UpdateItem, DeleteItem, BatchWriteItem und TransactWriteItems.

Wenn Sie eine PutItem-, UpdateItem-, DeleteItem- oder BatchWriteItem-Anforderung an DAX senden, werden die folgenden Vorgänge ausgeführt:

  • DAX sendet die Anforderung an DynamoDB.

  • DynamoDB antwortet DAX und bestätigt den erfolgreichen Schreibvorgang.

  • DAX schreibt das Element in den Element-Cache.

  • DAX gibt eine Erfolgsmeldung an den Anforderer zurück.

Wenn Sie eine TransactWriteItems-Anforderung an DAX senden, werden die folgenden Vorgänge ausgeführt:

  • DAX sendet die Anforderung an DynamoDB.

  • DynamoDB antwortet DAX und bestätigt, dass die Transaktion abgeschlossen ist.

  • DAX gibt eine Erfolgsmeldung an den Anforderer zurück.

  • DAX stellt im Hintergrund eine TransactGetItems-Anforderung für jedes Element in der TransactWriteItems-Anforderung, um das Element im Element-Cache zu speichern. TransactGetItems wird verwendet, um die serialisierbare Isolierung sicherzustellen.

Wenn bei einem Schreibvorgang für DynamoDB ein Fehler auftritt, einschließlich Drosselung, wird das Element in DAX nicht im Cache gespeichert. Die Ausnahme für den Fehler wird an den Anforderer zurückgegeben. So wird sichergestellt, dass keine Daten in den DAX-Cache geschrieben werden, es sei denn, sie wurden vorher erfolgreich in DynamoDB geschrieben.

Anmerkung

Mit jedem Schreibvorgang in DAX wird der Status des Element-Caches geändert. Schreibvorgänge in den Element-Cache wirken sich nicht auf den Abfrage-Cache aus. (Der DAX-Element-Cache und Abfrage-Cache werden für unterschiedliche Zwecke verwendet und arbeiten unabhängig voneinander.)

Verhalten des DAX-Abfrage-Caches

DAX speichert die Ergebnisse von Query und Scan-Anforderungen im Abfrage-Cache. Diese Ergebnisse wirken sich jedoch nicht auf den Element-Cache aus. Wenn Ihre Anwendung eine Query- oder Scan- Anforderung mit DAX erstellt, wird der Ergebnissatz im Abfrage-Cache und nicht im Element-Cache gespeichert. Sie können den Element-Cache nicht "warmlaufen" lassen, indem Sie eine Scan-Operation ausführen, da der Element-Cache und der Abfrage-Cache zwei verschiedene Entitäten sind.

Konsistenz der Schritte Abfragen, Aktualisieren, Abfragen

Durch Aktualisierungen des Element-Caches oder der zugrunde liegenden DynamoDB-Tabelle werden die im Abfrage-Cache gespeicherten Ergebnisse nicht ungültig oder geändert.

Berücksichtigen Sie zur Veranschaulichung das folgende Szenario. Eine Anwendung arbeitet mit der DocumentRevisions-Tabelle, deren Partitionsschlüssel DocId und Sortierschlüssel RevisionNumber lautet.

  1. Ein Client erstellt eine Query für DocId101, für alle Elemente mit RevisionNumber größer als oder gleich 5. DAX speichert den Ergebnissatz im Abfrage-Cache und gibt ihn an den Benutzer zurück.

  2. Der Client gibt eine PutItem-Anforderung für die DocId 101 mit dem RevisionNumber-Wert 20 aus.

  3. Der Client erstellt dieselbe Query wie in Schritt 1 beschrieben (DocId 101 und RevisionNumber >= 5).

In diesem Szenario ist der zwischengespeicherte Ergebnissatz für die in Schritt 3 erstellte Query mit dem Ergebnissatz identisch, der in Schritt 1 zwischengespeichert wurde. Der Grund ist, dass DAX Query - oder Scan-Ergebnissätze basierend auf Aktualisierungen einzelner Elemente nicht ungültig macht. Die PutItem-Operation aus Schritt 2 wirkt sich nur auf den DAX-Abfrage-Cache aus, wenn die TTL für die Query abläuft.

Ihre Anwendung sollte den TTL-Wert für den Abfrage-Cache und die Dauer berücksichtigen, wie lange Ihre Anwendung inkonsistente Ergebnisse zwischen dem Abfrage- und dem Element-Cache tolerieren kann.

Strongly Consistent- und Transactional-Lesevorgänge

Zum Ausführen einer Strongly-Consistent- GetItem, BatchGetItem, Query, oder ScanAnforderung, legen Sie den ConsistentRead Parameter auf „true“ fest. DAX übergibt Strongly-Consistent-Leseanforderungen an DynamoDB. Wenn eine Antwort von DynamoDB eingeht, gibt DAX die Ergebnisse an den Client zurück, speichert sie jedoch nicht im Cache. DAX kann selbst keine Strongly-Consistent-Lesevorgänge ausführen, da keine enge Kopplung an DynamoDB besteht. Aus diesem Grund müssen alle nachfolgenden Lesevorgänge aus DAX vom Typ Eventually Consistent sein. Nachfolgende Strongly-Consistent-Lesevorgänge müssen an DynamoDB übergeben werden

DAX verarbeitet TransactGetItems-Anforderungen genauso wie Strongly Consistent-Lesevorgänge. DAX übergibt alle TransactGetItems-Anforderungen an DynamoDB. Wenn eine Antwort von DynamoDB eingeht, gibt DAX die Ergebnisse an den Client zurück, speichert sie jedoch nicht im Cache.

Negative Cache-Speicherung

DAX unterstützt negative Cache-Einträge, und zwar sowohl im Element- als auch im Abfrage-Cache. Ein negativer Cache-Eintrag tritt auf, wenn DAX in einer zugrunde liegenden DynamoDB-Tabelle keine angeforderten Elemente finden kann. Statt einen Fehler zu melden, legt DAX ein leeres Ergebnis im Cache ab und gibt dieses Ergebnis an den Benutzer zurück.

Angenommen, eine Anwendung sendet eine GetItem-Anforderung an einen DAX-Cluster und es befindet sich kein übereinstimmendes Element im DAX-Element-Cache. Dies führt dazu, dass DAX das entsprechende Element aus der zugrunde liegenden DynamoDB-Tabelle liest. Wenn das Element in DynamoDB nicht existiert, speichert DAX ein leeres Element im Element-Cache und gibt dieses leere Element an die Anwendung zurück. Angenommen, die Anwendung sendet eine andere GetItem-Anforderung für das gleiche Element. DAX findet das leere Element im Element-Cache und gibt es sofort an die Anwendung zurück. Auf DynamoDB wird dabei nicht zurückgegriffen.

Ein negativer Cache-Eintrag bleibt im DAX-Element-Cache, bis die Element-TTL abgelaufen ist, LRU aufgerufen oder das Element mit PutItem, UpdateItem, oder DeleteItem geändert wird.

Der DAX-Abfrage-Cache verarbeitet negative Cache-Ergebnisse ähnlich. Wenn eine Anwendung eine Query- oder Scan-Operation ausführt und der DAX-Abfrage-Cache kein Ergebnis enthält, sendet DAX die Anforderung an DynamoDB. Wenn keine übereinstimmenden Elemente im Ergebnissatz vorhanden sind, speichert DAX einen leeren Ergebnissatz im Abfrage-Cache und gibt den leeren Ergebnissatz an die Anwendung zurück. Bei nachfolgenden Query- oder Scan-Anforderungen ergibt sich derselbe (leere) Ergebnissatz, bis die TTL für diesen Ergebnissatz abgelaufen ist.

Strategien für Schreibvorgänge

Das Write-Through-Verhalten von DAX eignet sich für viele Anwendungsmuster. Für einige Anwendungsmuster ist ein Write-Through-Modell allerdings nicht geeignet.

Bei Anwendungen, die latenzempfindlich sind, führt die Write-Through-Methode für DAX zu einem zusätzlichen Netzwerk-Hop. Ein Schreibvorgang in DAX ist daher etwas langsamer als ein Schreibvorgang, der direkt in DynamoDB ausgeführt wird. Wenn Ihre Anwendung schreiblatzenzempfindlich ist, können Sie die Latenz reduzieren, indem Sie stattdessen direkt in DynamoDB schreiben. Weitere Informationen finden Sie unter Write-Around.

Für schreibintensive Anwendungen (z. B. Anwendungen, die ein Massenladen von Daten ausführen) empfiehlt es sich nicht, alle Daten über DAX zu schreiben, da nur ein kleiner Anteil der Daten von der Anwendung gelesen wird. Wenn Sie große Datenmengen über DAX schreiben, muss der entsprechende LRU-Algorithmus aufgerufen werden, um Platz im Cache für die neuen, zu lesenden Elemente zu schaffen. Hierdurch wird die Effektivität von DAX als Lese-Cache beeinträchtigt.

Wenn Sie ein Element in DAX schreiben, wird der Status des Element-Caches für das neue Element geändert. (DAX muss z. B. ältere Daten aus dem Element-Cache entfernen, um Platz für das neue Element bereitzustellen.) Das neue Element bleibt im Element-Cache, abhängig vom LRU-Algorithmus des Caches und von der TTL-Einstellung für den Cache. Solange das Element im Element-Cache gespeichert bleibt, liest DAX das Element nicht erneut aus DynamoDB.

Write-Through

Der DAX-Element-Cache implementiert eine Write-Through-Richtlinie. Weitere Informationen finden Sie unter Wie DAX Schreibzugriffe verarbeitet.

Wenn Sie ein Element schreiben, stellt DAX sicher, dass das zwischengespeicherte Element mit dem Element so synchronisiert wird, wie es in DynamoDB vorhanden ist. Dies ist hilfreich für Anwendungen, die ein Element erneut lesen müssen, unmittelbar nachdem sie es geschrieben haben. Wenn andere Anwendungen jedoch direkt in eine DynamoDB-Tabelle schreiben, ist das Element im DAX-Element-Cache nicht mehr mit DynamoDB synchronisiert.

Nehmen wir folgendes Beispiel zur Veranschaulichung. Angenommen, zwei Benutzer (Alice und Bob) arbeiten mit der Tabelle ProductCatalog. Alice greift mit DAX auf die Tabelle zu, während Bob DAX umgeht und direkt in DynamoDB auf die Tabelle zugreift.

Workflow-Diagramm mit den nummerierten Schritten, mit denen die Benutzer Alice und Bob mithilfe von DAX und DynamoDB auf eine Tabelle zugreifen.
  1. Alice aktualisiert ein Element in der ProductCatalog-Tabelle. DAX leitet die Anforderung an DynamoDB weiter und die Aktualisierung wird erfolgreich ausgeführt. Anschließend schreibt DAX das Element in den Element-Cache und gibt die Antwort, dass der Vorgang erfolgreich ausgeführt wurde, an Alice zurück. Von diesem Zeitpunkt an sieht jeder Benutzer, der das Element aus DAX liest, das Element mit der Aktualisierung von Alice, bis das Element letztendlich aus dem Cache entfernt wird.

  2. Kurze Zeit später aktualisiert Bob dasselbe ProductCatalog-Element, das Alice geschrieben hat. Bob aktualisiert das Element jedoch direkt in DynamoDB. DAX aktualisiert den Element-Cache nicht automatisch als Reaktion auf Aktualisierungen über DynamoDB. Daher sehen DAX-Benutzer Bobs Aktualisierung nicht.

  3. Alice liest das Element erneut aus DAX. Das Element befindet sich im Element-Cache, sodass DAX es an Alice zurückgibt, ohne auf die DynamoDB-Tabelle zuzugreifen.

In diesem Szenario sehen Alice und Bob unterschiedliche Darstellungen desselben ProductCatalog-Elements. Dies ist der Fall, bis DAX das Element letztendlich aus dem Element-Cache entfernt oder bis ein anderer Benutzer dasselbe Element mit DAX erneut aktualisiert.

Write-Around

Wenn die Anwendung große Datenmengen (z. B. ein Massenladen von Daten) schreiben muss, kann es sinnvoll sein, DAX zu umgehen und die Daten direkt in DynamoDB zu schreiben. Diese Write-Around-Strategie reduziert die Schreiblatenz. Der Element-Cache bleibt allerdings nicht mit den Daten in DynamoDB synchronisiert.

Wenn Sie eine Write-Around-Strategie verwenden möchten, denken Sie daran, dass DAX den Element-Cache füllt, sobald Anwendungen den DAX-Client zum Lesen von Daten verwenden. Dies kann in einigen Fällen von Vorteil sind, da sichergestellt wird, dass nur die am häufigsten gelesenen Daten zwischengespeichert werden (im Gegensatz zu den am häufigsten geschriebenen Daten).

Beispiel: Ein Benutzer (Charlie) möchte unter Verwendung von mit einer anderen Tabelle arbeiten, und zwar mit der GameScoresTabelle, die DAX nutzt. Der Partitionsschlüssel für GameScores ist UserId, sodass alle Punktzahlen von Charlie dieselbe UserId hätten.

Workflow-Diagramm mit den nummerierten Schritten, in denen Charlie in DAX mit einer DynamoDB-Tabelle arbeitet.
  1. Charlie möchte seine gesamten Ergebnisse abrufen und sendet eine Query an DAX. Unter der Annahme, dass diese Abfrage noch nicht erstellt wurde, leitet DAX die Abfrage zur Verarbeitung an DynamoDB weiter. Die Ergebnisse werden im DAX-Abfrage-Cache gespeichert und an Charlie zurückgegeben. Der Ergebnissatz bleibt im Abfrage-Cache verfügbar, bis er entfernt wird.

  2. Angenommen, Charlie spielt das Spiel Meteor Blaster und erzielt eine hohe Punktzahl. Charlie sendet eine UpdateItem-Anforderung an DynamoDB und ändert ein Element in der GameScores Tabelle.

  3. Schließlich beschließt Charlie, seine frühere Query erneut auszuführen, um alle seine Daten aus GameScores abzurufen. In den Ergebnissen ist die hohe Punktzahl für Meteor Blaster nicht enthalten. Der Grund hierfür ist, dass die Abfrageergebnisse aus dem Abfrage-Cache und nicht aus dem Element-Cache stammen. Die beiden Caches sind unabhängig voneinander, sodass sich eine Änderung des einen Caches nicht auf den anderen auswirkt.

DAX aktualisiert keine Ergebnissätze im Abfrage-Cache mit den neuesten Daten aus DynamoDB. Jeder Ergebnissatz im Abfrage-Cache entspricht dem Zeitpunkt, an dem die Query- oder Scan-Operation durchgeführt wurde. Daher werden Charlies Query-Ergebnisse nicht in seiner PutItem-Operation berücksichtigt. Dies ist so lange der Fall, bis DAX den Ergebnissatz aus dem Abfrage-Cache entfernt.