Fortgeschritten5 Min. Lesezeit

DynamoDB: stark konsistente vs. letztendlich konsistente Reads

Du aktualisierst ein Item, liest es sofort zurück und bekommst den alten Wert. Der Write gelang — einen Moment später gibt derselbe Read den neuen Wert zurück. Nichts ist kaputt: Du bist auf DynamoDBs voreingestellten letztendlich konsistenten Read gestoßen, und du kannst pro Request darauf verzichten.

Das ist einer der wenigen Korrektheitsregler, die DynamoDB dir direkt in die Hand gibt, und er hat einen echten Preis. Ihn richtig einzusetzen heißt zu wissen, was jeder Modus garantiert, was er kostet und wo stark konsistente Reads schlicht nicht verfügbar sind.

Was ist der Unterschied zwischen stark und letztendlich konsistenten Reads in DynamoDB?

Ein letztendlich konsistenter Read (der Standard) wird von einem beliebigen Replikat bedient und kann daher direkt nach einem Write kurz veraltete Daten zurückgeben, kostet dafür aber nur halb so viel. Ein stark konsistenter Read, pro Request mit ConsistentRead=true aktiviert, wird zum Leader der Partition geroutet und spiegelt immer jeden committeten Write wider — bei der doppelten Lesekapazität.

  • Letztendlich konsistent (der Standard) — kann direkt nach einem Write kurz veraltete Daten zurückgeben. Der günstigste Lesemodus.
  • Stark konsistent — spiegelt immer jeden Write wider, der vor dem Read committet wurde. Pro Request mit ConsistentRead=true aktivierbar.
  • Stark konsistente Reads kosten das 2-fache eines letztendlich konsistenten Reads. Ein stark konsistenter Read verbraucht für dieselben Daten die doppelte Lesekapazität eines letztendlich konsistenten Reads.
  • Nicht überall. Stark konsistente Reads bekommst du auf der Basistabelle und auf einem Local Secondary Index. Ein Global Secondary Index ist nur letztendlich konsistent — kein Opt-in.
  • Standardmäßig letztendlich konsistent. Greif nur dann zu stark konsistenten Reads, wenn du deine eigenen, gerade geschriebenen Daten liest und "einen Moment veraltet" falsch wäre.

Das Problem: ein Read, der den letzten Write nicht sieht

Sagen wir, du betreibst User-Accounts. Ein User ändert seine Benachrichtigungs-E-Mail, deine App schreibt das Update, und der Bestätigungsbildschirm liest das Profil sofort neu, um die neue Adresse zu zeigen. Im voreingestellten Lesemodus kann dieser Re-Read auf einem Replikat landen, das die Änderung noch nicht erhalten hat — also sieht der User seine alte E-Mail und nimmt an, das Speichern sei fehlgeschlagen.

Das Fenster ist klein (üblicherweise deutlich unter einer Sekunde) und es schließt sich von selbst. Aber "meistens korrekt" ist für eine Read-after-Write-Bestätigung nicht gut genug. Genau für diesen Fall existiert starke Konsistenz.

Warum letztendliche Konsistenz passiert

DynamoDB speichert jede Partition auf drei Speicherknoten — einem Primary und zwei Replikaten — über separate Availability Zones hinweg. Ein Write wird bestätigt, sobald er auf dem Primary und einem Replikat landet; er propagiert dann asynchron zum dritten Knoten.

Reads können, um die Last zu verteilen, von jedem der drei Knoten bedient werden. Ein letztendlich konsistenter Read kann einen Knoten treffen, der deinen jüngsten Write noch nicht erhalten hat — also gibt er einen leicht veralteten Wert zurück. Ein stark konsistenter Read wird zum Leader der Partition geroutet, der immer die zuletzt committeten Daten hält, sodass er nie veraltete Ergebnisse zurückgibt.

synchron, bestätigtasynchron, hinkt kurz hinterherkann einen hinterherhinkendenNode treffenWrite: neue E-MailPrimary-NodeReplikat 1Replikat 2Stark konsistenter ReadEventually-consistent-Read

Diese Replikationsverzögerung ist der ganze Unterschied. Sie erklärt auch die 2-fachen Kosten: Stark konsistente Reads können nicht wie letztendlich konsistente Reads über die Replikate lastverteilt werden, also bepreist DynamoDB sie mit der doppelten Kapazität.

Die Kosten, konkret gemacht

Reads werden in Read Capacity Units (RCU) gemessen, jede deckt bis zu 4 KB ab. Eine RCU kauft einen stark konsistenten Read oder zwei letztendlich konsistente Reads eines 4-KB-Items. Wenn du also ConsistentRead=true auf einem heißen Lesepfad umlegst, verdoppelst du dessen Lesekosten — auf einem stark frequentierten Endpoint ist das ein Posten, den du bemerken wirst.

Modelliere den Unterschied für deine eigenen Item-Größen und Request-Raten mit dem DynamoDB-Preisrechner, bevor du stark konsistente Reads zu deinem Standard machst — es lohnt sich selten, durchweg doppelt zu zahlen.

Wo stark konsistente Reads verfügbar sind (und wo nicht)

Read gegenStark konsistent?
BasistabelleJa — Opt-in mit ConsistentRead=true
Local Secondary Index (LSI)Ja — gleiches Opt-in wie die Basistabelle
Global Secondary Index (GSI)Nein — nur letztendlich konsistent, kein Override

Ein GSI hält seine eigene Kopie der Daten, asynchron aus der Basistabelle repliziert, also kann er nie einen stark konsistenten Read anbieten. Wenn ein Zugriffsmuster echt Read-after-Write braucht und du es aus einem GSI bedienen wolltest, ist das ein Signal, es stattdessen aus der Basistabelle oder einem LSI zu bedienen.

Fallstricke und nächste Schritte

  • Mach stark konsistente Reads nicht zum Standard. Die meisten Reads tolerieren ein Sub-Sekunden-Veraltungsfenster; überall das 2-fache zu zahlen ist verschwendetes Geld.
  • Erwarte kein Read-after-Write von einem GSI. Er ist per Design letztendlich konsistent — siehe warum ein GSI letztendlich konsistent ist.
  • Transaktionen lesen stark konsistent. TransactGetItems ist immer stark konsistent — siehe DynamoDB-Transaktionen.
  • Konsistenz beeinflusst die Kapazität. Der 2-fach-Multiplikator hängt direkt mit der Kostenplanung von On-Demand vs. Provisioned zusammen.

Willst du deine DynamoDB-Tabellen und -Indizes erkunden, ohne API-Aufrufe zu schreiben? Lade DynoTable herunter und inspiziere deine Daten direkt.

Aktualisiert