Profi6 Min. Lesezeit

Wie DynamoDB-Storage-Internals funktionieren

DynamoDB ist eine Hashtabelle, deren Werte sortierte Bäume sind, verteilt über Maschinen in drei Availability Zones. Zwei Datenstrukturen leisten fast die ganze Arbeit: Ein Hash auf dem Partition Key wählt eine Maschine, ein B-Baum auf dem Sort Key ordnet Items darin.

Wie speichert DynamoDB Daten?

DynamoDB speichert deine Daten als riesige verteilte Hashtabelle, deren Werte sortierte B-Bäume sind. Ein Hash auf dem Partition Key wählt eine Storage-Node; ein B-Baum ordnet Items darin nach Sort Key. Jeder Write wird synchron auf drei Nodes in drei Availability Zones repliziert, bevor er bestätigt wird.

  • Der Partition Key wird gehasht, nicht durchsucht. DynamoDB jagt eine Hash-Funktion über deinen PK, um die eine Storage-Node zu finden, die diese Partition hält — ein O(1)-Sprung, unabhängig von der Tabellengröße.
  • Der Sort Key lebt in einem B-Baum. Innerhalb einer Partition werden Items in einem B-Baum gespeichert, lexikografisch nach SK geordnet, weshalb Bereichs-Reads (begins_with, between) billig sind und Scan nicht.
  • Jeder Write trifft drei Nodes, bevor er ackt. Ein Write geht an einen Leader, der synchron zu zwei Peers in anderen AZs repliziert — Dauerhaftigkeit ist gekauft, bevor dein PutItem zurückkehrt.
  • Deshalb existieren die Access-Pattern-Regeln. Hash-dann-Baum ist nur schnell, wenn du nach Key liest. Kein Key, kein schneller Pfad — du fällst zurück aufs Scannen des Baums.

Beginne mit der Datenstruktur, nicht der API

Von SQL kommend stellst du dir eine Tabelle als Zeilen auf der Platte vor, mit einem Query-Planner, der Indizes wählt. DynamoDB hat keinen Planner. Das Storage-Layout ist der Vertrag — was schnell ist und was ein Footgun ist, fällt beides direkt aus zwei Strukturen.

Stell dir eine riesige verteilte Map vor. Der Key ist ein Hash deines Partition Keys. Der Wert ist kein einzelnes Item — er ist ein ganzer B-Baum von Items, die sich diesen Partition Key teilen, geordnet nach Sort Key.

Alles andere — Query-Semantik, die 10-GB-Warnungen, warum ein fehlender Key einen Scan erzwingt — ist eine Konsequenz dieses einen Satzes.

Den Partition Key hashen, um die Node zu finden

Wenn ein Request ankommt, wendet DynamoDB eine interne Hash-Funktion auf den Partition-Key-Wert an. Der Hash bildet deterministisch auf eine Storage-Node ab — die physische Partition, die diese Items besitzt. AWS dokumentiert das als den Mechanismus hinter Key-Lookups in konstanter Zeit, unabhängig von der Tabellengröße.

Das ist der O(1)-Schritt. Eine 10-TB-Tabelle und eine 10-KB-Tabelle kosten gleich viel zum Lokalisieren: hashen, springen, fertig. Es gibt keinen Index-Scan, um die Node zu finden, keine Statistiken, keinen Plan.

Der Haken ist die Kehrseite. Wenn du den Partition Key nicht lieferst, hat DynamoDB keine Node zum Springen — es muss jede Partition ablaufen. Das ist ein Scan, und es ist der Unterschied zwischen O(1) und dem Lesen der ganzen Tabelle.

PutItem / GetItemPK=DEVICE#a91Hash(PK)Storage-Node(eine Partition)B-Baum auf SKREADING#... geordnetItem

Der Request hasht auf genau eine Partition, dann steigt er den Sort-Key-B-Baum dieser Partition zum Item hinab — zwei billige Schritte statt eines Tabellendurchlaufs.

Items in einem Per-Partition-B-Baum ordnen

Innerhalb einer einzelnen Partition sind Items kein Heap. Sie werden in einem B-Baum, verschlüsselt nach dem Sort Key, gehalten, lexikografisch geordnet. Eine B-Baum-Suche ist O(log n), und entscheidend ist dieses n die Items in einer Partition, nicht der ganzen Tabelle.

Das ist der ganze Grund, warum Sort-Key-Bereichs-Reads billig sind. Nimm eine Fleet-Telemetrie-Tabelle, wo die Messungen jedes Geräts unter einem Partition Key leben:

PKSK
PK = DEVICE#a91SK = READING#2026-06-23T08:00Z
PK = DEVICE#a91SK = READING#2026-06-23T08:05Z
PK = DEVICE#a91SK = READING#2026-06-23T08:10Z

Weil der B-Baum sortiert ist, ist „alle Messungen zwischen 08:00 und 09:00" ein Baumabstieg zum Startwert plus ein sequenzieller Lauf — kein Filter über jede Messung, die das Gerät je gesendet hat. Du liest nur den gematchten Bereich.

Diese Ordnung ist auch, warum eine begins_with(SK, "READING#2026-06-23")-Query schnell ist, während Filtern auf einem Nicht-Key-Attribut es nicht ist. Der Baum kann nach SK seeken; er kann nach nichts anderem seeken. Um diese Key-Bedingungen sicher zusammenzusetzen, baue sie im DynamoDB Expression Builder, statt Strings von Hand zu verketten:

KeyConditionExpression  PK = :pk AND begins_with(SK, :day)

Jeden Write in drei AZs replizieren

Eine Partition ist nicht eine Maschine. Jede ist über drei Nodes in drei Availability Zones repliziert — eine Design-Abstammung, die bis zum Replikationsmodell des Amazon-Dynamo-Papers von 2007 zurückreicht.

Eine Node ist der Leader für die Partition. Ein Write geht an den Leader, der lokal schreibt und zu seinen zwei Peers repliziert. Der Leader ackt den Write, sobald ein dauerhaftes Quorum von Nodes ihn hat — sodass Dauerhaftigkeit über AZs bezahlt ist, bevor dein PutItem zurückkehrt.

Reads haben eine Wahl. Ein stark konsistenter Read geht an den Leader und sieht den letzten committeten Write. Ein letztendlich konsistenter Read kann von jeder der drei Nodes bedient werden, von denen eine ein paar Millisekunden hinten sein kann — das ist die Verzögerung, die du gegen billigere, verfügbarere Reads tauschst.

Letztendlich konsistentStark konsistent
Bedient vonJede der 3 NodesNur Leader-Node
Sieht letzten WriteVielleicht (kleine Verzögerung)Immer
RCU-KostenHalbeVolle
VerfügbarkeitHöherNiedriger (einzelne Node)

Dieselbe Async-Propagationsidee ist, warum ein GSI-Read veraltet sein kann — siehe GSIs sind letztendlich konsistent.

Die Regeln aus der Struktur ablesen

Fast jede DynamoDB-„Regel" ist einfach Storage-Physik:

  • Liefere immer den Partition Key. Kein Key, kein Hash-Ziel — du scannst die ganze Map. Das ist der Kern von Query vs Scan.
  • Lokalisiere zusammen, was du zusammen liest unter einem Partition Key, sodass ein einzelner Hash + Baumlauf die ganze Item-Collection zurückgibt. Das ist die Grundlage von Single-Table-Design.
  • Halte Partitionen begrenzt. Eine Partition ist ein B-Baum auf einer endlichen Menge von Nodes; ein außer Kontrolle geratener Hot Key oder die 10-GB-Grenze eines LSI sind beides Limits dieser physischen Partition.

Sobald du die Hash-dann-B-Baum-Form siehst, hört die Access-Pattern-Disziplin auf, sich willkürlich anzufühlen — du hältst einfach jeden Read auf dem schnellen Pfad.

Nächste Schritte

Modelliere deine Keys passend zur Struktur mit Sort-Key-Strategien und Single-Table-Design, dann stelle die tatsächlichen Expressions im DynamoDB Expression Builder zusammen. Probiere DynoTable aus, um diese Reads gegen deine eigenen Tabellen laufen zu sehen und genau zu sehen, welche Items eine Key-Bedingung zurückzieht.

Aktualisiert