Profi7 Min. Lesezeit

Wie das Request-Routing von DynamoDB funktioniert

Jeder Lese- und Schreibvorgang, den du absetzt, trifft zuerst auf eine Flotte zustandsloser Request-Router. Ein Router hasht deinen , bildet den Hash auf den Storage-Knoten ab, dem die Daten dieses Keys gehören, und leitet den Request dorthin weiter. Dieser eine Hop ist der Grund, warum ein Key-Lookup dasselbe kostet, ob die Tabelle tausend Items hält oder eine Milliarde.

Wie funktioniert das Request-Routing von DynamoDB?

DynamoDB leitet jeden Request über eine zustandslose Request-Router-Flotte, die deinen hasht, den Hash auf den einen Storage-Knoten abbildet, dem diese Partition gehört, und den Lese- oder Schreibvorgang dorthin weitergibt. Routing ist eine reine Funktion des Key-Hashes, ein Lookup kostet also dasselbe, ob die Tabelle tausend Items hält oder eine Milliarde.

  • Der Request-Router ist die Eingangstür. Eine zustandslose Flotte, die deinen Request annimmt, den Partition Key hasht und ihn an den Storage-Knoten leitet, der diese Partition hält — ohne Scannen, ohne Wissen über die ganze Tabelle.
  • Der Partition Key entscheidet alles. Routing ist eine reine Funktion des Partition-Key-Hashes — derselbe Key landet immer bei der Partition, der er gehört, also ist GetItem O(1) und nicht O(Tabellengröße).
  • Ein Primary, zwei Secondaries. Ein Schreibvorgang landet auf dem Primärknoten der Partition, der bestätigt, sobald ein Quorum (zwei der drei Replikate) ihn persistiert hat.
  • Schlechte Keys hebeln das Design aus. Ein Partition Key mit geringer Kardinalität oder eine trichtert den Traffic auf einen Knoten — das Routing ist in Ordnung, dein Key ist das Problem.

Beginn beim Problem, das Routing löst

Aus der SQL-Welt stellst du dir einen Query-Planner vor: Er liest Statistiken, wählt einen Index, scannt vielleicht. Die Kosten skalieren damit, wie viele Daten er berührt. Dieses Modell passt nicht zu einem Key-Value-Store, der bei jeder Größe in einstelligen Millisekunden antworten muss.

Die Antwort von DynamoDB ist, ein Lookup auf ein einzelnes Item zu einer direkten Adresse zu machen, nicht zu einer Suche. Der Partition Key ist die Eingabe einer Hash-Funktion, die berechnet, wo die Daten physisch liegen — er ist keine Spalte, auf die du filterst. Keine Statistiken, kein Planner.

Das ist der Handel, den du eingehst, wenn du das relationale Denken verlässt: Du gibst Ad-hoc-Abfrageflexibilität auf und bekommst dafür Adressierung in konstanter Zeit.

Der Request-Router im Überblick

Wenn ein Request eintrifft, geht er nicht direkt zum Speicher. Er trifft auf einen Request-Router — eine zustandslose, horizontal skalierte Flotte, die dem ganzen Dienst vorgelagert ist. (Das DynamoDB-Paper von der USENIX ATC '22 beschreibt diese Request-Router-Flotte.)

Der Router tut drei Dinge und hält keine eigenen Daten:

  • Authentifiziert und autorisiert den Request gegen IAM.
  • Hasht den Partition Key, um die Partition zu finden, der er gehört.
  • Leitet den Request an den Storage-Knoten dieser Partition weiter.

Weil Router zustandslos sind, fügt der Dienst unter Last einfach weitere hinzu. Keiner davon ist ein Flaschenhals und keiner ein Single Point of Failure — dieselbe Eigenschaft, um die das Amazon-Dynamo-Paper von 2007 das ursprüngliche System herum gebaut hat.

Einen Lesevorgang durch den Router verfolgen

Nimm eine Telemetrietabelle für eine Drohnenflotte. Items sind über DroneId (Partition Key) und ReadingTs (Sort Key) gekeyt, mit Attributen wie BatteryPct und AltitudeM.

Du fragst die Messwerte einer Drohne vom 23. Juni ab:

PK = "DRONE#A19F"
SK begins_with "2026-06-23"

Das Diagramm unten verfolgt den Request von oben nach unten — lies es als einen Fluss nach unten.

Client: QueryPK = DRONE#A19FRequest-Router(zustandslose Flotte)Hash(DRONE#A19F) Keyspace-SlotSlot Partition mappen,die den Schlüssel besitztPrimärknotendieser PartitionItem lesenDRONE#A19F

Der Router hasht DRONE#A19F, bildet ihn auf die Partition ab, der dieser Key gehört, und leitet den Lesevorgang an den primären Storage-Knoten dieser Partition weiter, der das Item zurückgibt.

Der Hash zeigt auf eine Partition — von wie vielen die Tabelle auch immer hat. Der Router sieht sich andere Partitionen nie an, also bremsen zusätzliche Drohnen — und Partitionen — dieses Lookup nicht aus.

Was eine Partition eigentlich ist

Eine Partition ist eine Einheit aus Speicher und Durchsatz. Jede ist gedeckelt (grob 10 GB und eine feste Scheibe Lese-/Schreibkapazität), und DynamoDB teilt eine Partition, wenn sie eines der Limits sprengt. Jedes Item mit einem bestimmten Partition Key startet auf einer Partition; Split-for-Heat kann diese Collection später nach Sort-Key-Bereich zerlegen (sofern kein LSI oder monotoner Sort Key das festnagelt) — und genau das macht eine Query über einen Partition Key weiterhin günstig.

Jede Partition wird auf drei Storage-Knoten repliziert, verteilt über Availability Zones: ein Primary und zwei Secondaries.

KnotenrolleBearbeitetKonsistenz, die er liefern kann
PrimaryAlle Schreibvorgänge; stark konsistente ReadsStark (sieht seinen eigenen letzten Schreibvorgang)
SecondaryLetztendlich konsistente Reads; FailoverLetztendlich (kann dem Primary hinterherhinken)

Ein Schreibvorgang geht an den Primary, der ihn bestätigt, sobald ein Quorum (zwei der drei Replikate) ihn persistiert hat. Ein Lesevorgang wird an den Primary geleitet, damit er den letzten Schreibvorgang widerspiegelt. Ein Lesevorgang kann von einem Secondary bedient werden, der noch nicht aufgeholt hat — halber Preis, möglicherweise veraltet.

Das Footgun beim Namen nennen: ein heißer Partition Key

Routing ist nur so gut wie dein Partition Key. Der Hash verteilt Keys gleichmäßig: Haben deine Keys also hohe Kardinalität und gleichmäßigen Traffic, verteilt sich die Last über alle Knoten. Brichst du eine der beiden Eigenschaften, bekommst du eine heiße Partition.

Angenommen, du keyst diese Telemetrie nach Region statt nach DroneId. Jetzt teilen sich alle Drohnen in us-east-1 einen Partition Key — ihre Lese- und Schreibvorgänge hashen also auf denselben Keyspace-Slot und stapeln sich in einer Item Collection. Der Router macht seine Arbeit perfekt; du hast nur die ganze Flotte auf die Kapazität einer einzigen Partition getrichtert.

Du kannst dem Router nicht dabei zusehen, wie er einen Knoten wählt, aber du kannst Keys entwerfen, die gut routen. Wenn du im Expression Builder eine Key-Bedingung baust, ist der Partition Key, den du links von PK = … schreibst, genau der Wert, den der Router hashen wird — diesen Wert mit hoher Kardinalität zu halten, hält Lesevorgänge auf getrennten Knoten.

Wie das auf deine Zugriffsmuster zurückwirkt

Request-Routing ist der Mechanismus, der die Regeln von Single-Table-Design nicht verhandelbar macht: Du modellierst rund um den Partition Key, weil der Partition Key die Adresse ist. Es ist auch der Grund, warum eine Query einen Scan schlägt — eine Query trifft über den Router eine Partition, während ein Scan jede Partition der Reihe nach abläuft.

Secondary Indexes bekommen eigene Partitionen und ein eigenes Routing: Eine GSI wird über ihren eigenen Partition Key geroutet, unabhängig von dem der Basistabelle — deshalb kann eine GSI heiß sein, auch wenn die Tabelle es nicht ist.

Nächste Schritte

Entwirf Keys, die auf viele Knoten routen, nicht auf einen. Skizziere die Bedingung PK = … im Expression Builder, um genau zu sehen, welcher Wert gehasht wird, und lade dann DynoTable herunter, um diese Abfragen gegen deine eigenen Tabellen laufen zu lassen und zu sehen, was jede Key-Bedingung genau zurückgibt.

Aktualisiert