8 Min

Amazon DynamoDB erklärt: Aufbau skalierbarer Systeme

Erfahre, was Amazon DynamoDB ist, wie sein NoSQL‑Modell funktioniert und welche Designmuster für skalierbare, niedrig-latente Systeme und Microservices praxisnah sind.

Amazon DynamoDB erklärt: Aufbau skalierbarer Systeme

Was DynamoDB ist und warum Teams es nutzen

Amazon DynamoDB ist ein vollständig verwalteter NoSQL-Datenbankdienst von AWS, ausgelegt für Anwendungen, die konsistent niedrige Latenz bei Lese- und Schreibzugriffen in praktisch beliebigem Maßstab benötigen. „Vollständig verwaltet“ bedeutet, dass AWS Infrastrukturaufgaben übernimmt—Hardware-Provisionierung, Replikation, Patching und viele operative Aufgaben—sodass Teams sich auf das Ausliefern von Features statt auf den Betrieb von Datenbankservern konzentrieren können.

Im Kern speichert DynamoDB Daten als Items (Zeilen) in Tabellen, wobei jedes Item flexible Attribute haben kann. Das Datenmodell ist am besten als Mischung aus:

  • Key-Value: ein Item schnell über seinen Primärschlüssel abrufen, ähnlich wie das Nachschlagen eines Datensatzes per ID.
  • Document: verschachtelte Attribute (Maps und Listen) speichern, ähnlich JSON, nützlich für zusammenhängende Felder ohne strikten Schemazwang.

Teams wählen DynamoDB, wenn sie vorhersehbare Leistung und einfachere Betriebsführung für Workloads möchten, die nicht gut in relationale Joins passen. Häufige Anwendungsfälle sind Microservices (jeweils eigener Datenbesitz), serverlose Apps mit burstigem Traffic und ereignisgesteuerte Systeme, die auf Datenänderungen reagieren.

Dieser Beitrag erläutert die Bausteine (Tabellen, Keys und Indizes), wie man um Zugriffs‑Patterns modelliert (inklusive Single-Table-Design), wie Skalierung und Kapazitätsmodi funktionieren und praktische Muster, um Änderungen in eine ereignisgesteuerte Architektur zu streamen.

Kernkonzepte: Tabellen, Items und Primärschlüssel

DynamoDB ist um einige einfache Bausteine herum organisiert, aber die Details sind wichtig, weil sie bestimmen, wie du Daten modellierst und wie schnell (und kosteneffizient) Anfragen sind.

Tabellen, Items und Attribute

Eine Tabelle ist der oberste Container. Jeder Datensatz in einer Tabelle ist ein Item (ähnlich einer Zeile) und jedes Item ist eine Menge von Attributen (ähnlich Spalten).

Im Gegensatz zu relationalen DBs müssen Items in derselben Tabelle nicht dieselben Attribute teilen. Ein Item kann {status, total, customerId} haben, während ein anderes {status, shipmentTracking} enthält—DynamoDB verlangt kein festes Schema.

Primärschlüssel: einfach vs. zusammengesetzt

Jedes Item wird eindeutig durch einen Primärschlüssel identifiziert; DynamoDB unterstützt zwei Typen:

  • Einfacher Primärschlüssel (nur Partition Key): ein Attribut identifiziert jedes Item eindeutig.
  • Zusammengesetzter Primärschlüssel (Partition Key + Sort Key): mehrere Items können denselben Partition Key teilen, während der Sort Key sie unterscheidet und die Reihenfolge innerhalb dieser Partition bestimmt.

In der Praxis erlauben zusammengesetzte Schlüssel „gruppierte“ Zugriffs‑Patterns wie „alle Bestellungen eines Kunden, neueste zuerst“.

Query vs. Scan (auf hoher Ebene)

Eine Query liest Items über den Primärschlüssel (oder einen Indexschlüssel). Sie zielt auf einen spezifischen Partition Key und kann nach Sort Key-Bereichen filtern—das ist der effiziente, bevorzugte Pfad.

Ein Scan durchläuft die gesamte Tabelle (oder den Index) und filtert danach. Er ist einfach zu starten, aber normalerweise langsamer und teurer im großen Maßstab.

Grenzen, die man beachten sollte

Einige Einschränkungen, die früh spürbar werden:

  • Maximale Item-Größe: 400 KB.
  • Attributtypen: Skalare (String/Number/Binary/Boolean/Null), Sets, Lists und Maps.
  • Schlüsselattribute müssen skalar sein (keine Lists/Maps als Partition- oder Sort-Key).

Diese Grundlagen bestimmen alles Weitere: Zugriffs‑Patterns, Index‑Entscheidungen und Performance‑Charakteristika.

DynomoDBs Datenmodell: Key-Value und Document

DynamoDB wird oft sowohl als Key-Value-Store als auch als Dokumentdatenbank beschrieben. Das ist zutreffend, aber es hilft zu verstehen, was jedes Modell im täglichen Design bedeutet.

Key-Value-Zugriff vs. dokumentenartige Items

Im Kern holst du Daten per Key. Gib die Primärschlüsselwerte an und DynamoDB liefert ein einzelnes Item zurück. Diese Key-basierte Suche ist es, die für viele Workloads vorhersehbare, niedrig-latente Speicherung liefert.

Gleichzeitig kann ein Item verschachtelte Attribute (Maps und Lists) enthalten, was es wie eine Dokumentdatenbank wirken lässt: du kannst strukturierte Nutzlasten speichern, ohne ein starres Schema vorzugeben.

Hierarchische JSON-ähnliche Strukturen in Items modellieren

Items lassen sich natürlich auf JSON-ähnliche Daten abbilden:

  • Maps repräsentieren Objekte (z. B. profile.name, profile.address).
  • Lists repräsentieren Arrays (z. B. recent actions, tags).

Das passt gut, wenn eine Entität üblicherweise als Ganzes gelesen wird—wie ein Nutzerprofil, ein Warenkorb oder ein Konfigurationspaket.

Wann denormalisieren (und warum das üblich ist)

DynamoDB unterstützt keine serverseitigen Joins. Wenn deine App „eine Bestellung plus ihre Positionen plus Versandstatus“ in einem Lesezugriff benötigt, wirst du oft denormalisieren: Attribute in mehrere Items kopieren oder kleine Substrukturen direkt in ein Item einbetten.

Trade-offs gegenüber relationaler Normalisierung

Denormalisierung erhöht die Schreibkomplexität und kann Update‑Fan‑out erzeugen. Der Gewinn sind weniger Roundtrips und schnellere Lesezugriffe—oft der kritische Pfad in skalierbaren Systemen.

Partition Key und Sort Key: Entwurf entlang der Zugriffsmuster

Die schnellsten DynamoDB-Abfragen sind diejenigen, die du als „gib mir diese Partition“ (und optional „in dieser Partition gib mir diesen Bereich“) ausdrücken kannst. Deshalb geht es bei der Wahl der Keys hauptsächlich um wie du liest, nicht nur darum, wie du speicherst.

Partition Key: Verteilung und vorhersehbare Lesezugriffe

Der Partition Key bestimmt, welche physische Partition ein Item speichert. DynamoDB hasht diesen Wert, um Daten und Traffic zu verteilen. Wenn viele Anfragen sich auf eine kleine Menge von Partition Key Werten konzentrieren, entstehen „heiße“ Partitionen und du erreichst Durchsatzgrenzen, selbst wenn die Tabelle insgesamt kaum ausgelastet ist.

Gute Partition Keys:

  • Haben hohe Kardinalität (viele unterschiedliche Werte)
  • Passen zu einem häufigen Zugriffsmuster (so sind Reads direkt, nicht per Filter)
  • Vermeiden Werte, die sehr „populär“ werden (z. B. eine Konstante wie "GLOBAL")

Sort Key: Bereichsabfragen und gruppierte Entitäten

Mit einem Sort Key werden Items, die denselben Partition Key teilen, zusammen gespeichert und nach dem Sort Key geordnet. Das ermöglicht effiziente:

  • Range Queries (BETWEEN, begins_with)
  • Zeitlich geordnete Reads (neueste zuerst mit Reverse‑Scans)
  • Gruppierung von Entitäten (mehrere Item‑Typen unter einem Partition Key)

Ein übliches Muster ist das Zusammensetzen des Sort Keys, z. B. TYPE#id oder TS#2025-12-22T10:00:00Z, um mehrere Abfrageformen ohne zusätzliche Tabellen zu unterstützen.

Mapping gängiger Zugriffsmuster auf Keys

  • Get by ID: PK = USER#<id> (einfaches GetItem)
  • List by user: PK = USER#<id>, SK begins_with ORDER# (oder SK = CREATED_AT#...)
  • Time-series ranges: PK = DEVICE#<id>, SK = TS#<timestamp> mit BETWEEN für Zeitfenster

Wie die Key-Wahl Leistung und Skalierbarkeit beeinflusst

Wenn dein Partition Key mit deinen volumenstärksten Abfragen übereinstimmt und gleichmäßig verteilt ist, erhältst du konstant niedrige Latenzen für Reads und Writes. Wenn das nicht der Fall ist, kompensierst du mit Scans, Filtern oder zusätzlichen Indizes—das erhöht Kosten und das Risiko heißer Keys.

Sekundäre Indizes: GSI und LSI erklärt

Sekundäre Indizes geben DynamoDB alternative Abfragewege jenseits des Primärschlüssels deiner Tabelle. Anstatt die Basistabelle jedes Mal umzubauen, wenn ein neues Zugriffsmuster auftaucht, kannst du einen Index hinzufügen, der dieselben Items für eine andere Abfrage neu indiziert.

GSI vs. LSI: was ist der Unterschied?

Ein Global Secondary Index (GSI) hat einen eigenen Partition Key (und optionalen Sort Key), der sich komplett vom Tabellen‑Primärschlüssel unterscheiden kann. Er ist „global“, weil er alle Table‑Partitionen überschreitet und jederzeit hinzugefügt oder entfernt werden kann. Verwende einen GSI, wenn du ein neues Zugriffsmuster brauchst, das nicht zum ursprünglichen Key‑Design passt—z. B. Bestellungen nach customerId abfragen, wenn die Tabelle nach orderId geordnet ist.

Ein Local Secondary Index (LSI) teilt den gleichen Partition Key wie die Basistabelle, nutzt aber einen anderen Sort Key. LSIs müssen bei der Tabellenerstellung definiert werden. Sie sind nützlich, wenn du mehrere Sortierordnungen innerhalb derselben Entitätsgruppe (gleicher Partition Key) brauchst, z. B. Bestellungen eines Kunden nach createdAt vs. status.

Projektionen: was in den Index kopiert wird

Die Projektion bestimmt, welche Attribute DynamoDB im Index speichert:

  • KEYS_ONLY: günstigste Speicherung, aber häufig ist ein zusätzlicher Lesezugriff auf die Basistabelle nötig.
  • INCLUDE: kopiere nur die Attribute, die du meist zurückgibst.
  • ALL: am einfachsten, kann jedoch Speicher- und Schreibkosten aufblasen.

Schreibamplifikation (die versteckte Rechnung)

Jeder Schreibvorgang auf die Basistabelle kann Schreibvorgänge in einen oder mehrere Indizes auslösen. Mehr GSIs und breitere Projektionen erhöhen die Schreibkosten und den Kapazitätsbedarf. Plane Indizes um stabile Zugriffsmuster und halte projizierte Attribute möglichst minimal.

Kapazitätsmodi und Skalierungsverhalten

Für Streams-Events entwerfen
Skizzieren Sie einen ereignisgesteuerten Ablauf und binden Sie Handler für Änderungsereignisse mit einem per Chat erstellten Backend ein.

DynamoDB-Skalierung beginnt mit einer Wahl: On-Demand oder Provisioned Kapazität. Beide können sehr hohen Durchsatz erreichen, verhalten sich jedoch bei sich änderndem Traffic unterschiedlich.

On-Demand vs. Provisioned: wie man wählt

On-Demand ist am einfachsten: du zahlst pro Anfrage und DynamoDB passt sich automatisch an variable Last an. Es eignet sich für unvorhersehbaren Traffic, Early‑Stage-Produkte und spiky Workloads, bei denen du Kapazitätsziele nicht managen möchtest.

Provisioned ist Kapazitätsplanung: du gibst Lese- und Schreibdurchsatz an (oder stellst Auto‑Scaling ein) und erhältst vorhersehbarere Preise bei gleichmäßigem Verbrauch. Es ist oft günstiger bei bekanntem, konsistentem Workload und für Teams, die Nachfrage prognostizieren können.

Read/Write Kapazität in der Praxis

Provisioned Durchsatz wird gemessen in:

  • RCUs (Read Capacity Units): ungefähr ein starker konsistenter Lesezugriff pro Sekunde für bis zu 4 KB (oder zwei eventual konsistente Reads).
  • WCUs (Write Capacity Units): ungefähr ein Schreibvorgang pro Sekunde für bis zu 1 KB.

Deine Item-Größe und Zugriffsmuster bestimmen die echten Kosten: größere Items, starke Konsistenz und Scans verbrauchen Kapazität schnell.

Auto Scaling Grundlagen (und Grenzen)

Auto Scaling passt provisionierte RCUs/WCUs basierend auf Auslastungszielen an. Es hilft bei graduellem Wachstum und vorhersehbaren Zyklen, ist aber nicht sofort. Plötzliche Spitzen können weiterhin gedrosselt werden, wenn Kapazität nicht schnell genug hochfährt; außerdem löst es keine heißes‑Partition‑Probleme.

DAX: Caching für leseintensive Workloads

DynamoDB Accelerator (DAX) ist ein In‑Memory‑Cache, der Leseverzögerungen reduzieren und wiederholte Reads entlasten kann (z. B. beliebte Produktseiten, Session‑Lookups, Leaderboards). Er ist am nützlichsten, wenn viele Clients dieselben Items wiederholt anfragen; er hilft nicht bei schreibintensiven Mustern und ersetzt kein durchdachtes Key‑Design.

Konsistenz, Transaktionen und Korrektheit

DynamoDB erlaubt dir, Lesegarantien gegen Latenz und Kosten abzuwägen. Deshalb ist es wichtig, für jede Operation explizit zu definieren, was „korrekt“ bedeutet.

Eventually consistent vs. strongly consistent Reads

Standardmäßig verwenden GetItem und Query eventuell konsistente Reads: kurz nach einem Write kannst du noch einen älteren Wert sehen. Das ist oft ausreichend für Feeds, Produktkataloge und andere read‑schwere Views.

Mit stark konsistenten Reads (Option für Reads aus der Basistabelle in einer Region) garantiert DynamoDB, dass du die letzte bestätigte Schreiboperation siehst. Starke Konsistenz kostet mehr Read‑Kapazität und kann die Tail‑Latenz erhöhen, also setze sie für wirklich kritische Reads ein.

Wann starke Konsistenz wichtig ist

Starke Konsistenz ist wertvoll für Reads, die irreversible Aktionen steuern:

  • Prüfung verfügbarer Bestände vor Order‑Bestätigung
  • Ein Autorisierungsflag lesen, bevor Zugriff gewährt wird
  • Den aktuellen Zustand eines Workflows lesen, bevor der nächste Schritt ausgeführt wird

Bei Zählern ist der sicherste Ansatz meist kein „starkes Lesen dann Schreiben“, sondern ein atomares Update (z. B. UpdateItem mit ADD), sodass Inkremente nicht verloren gehen.

Transaktionale Reads/Writes

DynamoDB‑Transaktionen (TransactWriteItems, TransactGetItems) bieten ACID‑Semantik über bis zu 25 Items. Sie sind nützlich, wenn mehrere Items zusammen aktualisiert werden müssen—z. B. eine Bestellung anlegen und Inventar reservieren—oder um Invarianten durchzusetzen, die keine Zwischenzustände erlauben.

Idempotenz für sichere Retries

Retries sind normal in verteilten Systemen. Mache Writes idempotent, damit Retries Effekte nicht duplizieren:

  • Verwende ein Client Request Token (Idempotency Key), das mit dem Ergebnis gespeichert wird
  • Erzwinge Einzigartigkeit mit ConditionExpression (z. B. „only create if attribute_not_exists")
  • Bevorzuge atomare Updates gegenüber Lese‑Modifizieren‑Schreib‑Loops

Korrektheit in DynamoDB bedeutet meist, den richtigen Konsistenzlevel zu wählen und Operationen so zu gestalten, dass Retries die Daten nicht korrumpieren.

Partitionen, Hot Keys und Traffic‑Spitzen

DynamoDB verteilt Tabellendaten über mehrere physische Partitionen. Jede Partition hat begrenzten Durchsatz für Reads und Writes sowie eine Begrenzung, wie viel Daten sie speichern kann. Dein Partition Key bestimmt, wo ein Item liegt; wenn zu viele Anfragen denselben Partition Key Wert (oder eine kleine Menge von Werten) treffen, wird diese Partition zum Engpass.

Warum Hot Partitions entstehen

Hot Partitions entstehen meist durch Key‑Entscheidungen, die Traffic konzentrieren: ein „globaler“ Partition Key wie USER#1, TENANT#default oder STATUS#OPEN, oder zeitgeordnete Muster, bei denen alle unter einem Partition Key auf „now“ schreiben.

Symptome heißer Keys und ungleichmäßigen Traffics

Typische Anzeichen sind:

  • Throttling (ProvisionedThroughputExceededException) für eine Teilmenge von Keys
  • Erhöhte und spitze Latenz für einige Zugriffsmuster, während andere schnell bleiben
  • CloudWatch‑Metriken mit ungleichmäßigem konsumiertem Kapazitätsverhalten und plötzlichen Spitzen

Gegenmaßnahmen

Design für Verteilung zuerst, dann für Abfragekomfort:

  • Key‑Design: sorge für hoch‑kardinale Partition Keys (z. B. TENANT#<id> statt einer gemeinsamen Konstante)
  • Write‑Sharding: füge kleinen zufälligen oder gehashten Suffix/Präfix wie ORDER#<id>#<shard> hinzu, um Writes über N Shards zu verteilen, und frage bei Bedarf über die Shards hinweg ab
  • Zeit‑Buckets: nach Stunde/Tag bucketen (METRIC#2025-12-22T10) um zu verhindern, dass alle Writes in das aktuellste Item gehen

Umgang mit burstigen Workloads

Für unvorhersehbare Spitzen kann On‑Demand Kapazität Bursts absorbieren (innerhalb der Service‑Grenzen). Bei Provisioned Kapazität nutze Auto Scaling und implementiere clientseitig Exponential Backoff mit Jitter bei Throttles, um synchronisierte Retries zu vermeiden, die die Spitze verstärken.

Datenmodellmuster für skalierbare Systeme

Vom Modell zur laufenden Demo
Machen Sie in Minuten mit Koder.ai aus Zugriffsmustern eine funktionierende React‑App und Go‑API.

DynamoDB‑Datenmodellierung beginnt bei Zugriffs‑Patterns, nicht bei ER‑Diagrammen. Du entwirfst Keys so, dass die benötigten Abfragen zu schnellen Query‑Operationen werden, während alles andere vermieden oder asynchron behandelt wird.

Single‑Table‑Design (und warum Teams es mögen)

„Single‑Table‑Design“ bedeutet, mehrere Entitätstypen (Users, Orders, Messages) in einer Tabelle zu speichern und konsistente Key‑Konventionen zu verwenden, um verwandte Daten mit einer einzigen Query abzurufen. Das reduziert Cross‑Entity Roundtrips und hält die Latenz vorhersehbar.

Ein gängiger Ansatz sind zusammengesetzte Keys:

  • PK gruppiert eine logische Partition (z. B. USER#123)
  • SK ordnet Items innerhalb dieser Gruppe (z. B. PROFILE, ORDER#2025-12-01, MSG#000123)

Das erlaubt Abfragen wie „alles für einen User holen“ oder „nur Bestellungen eines Users“ durch Auswahl eines Sort‑Key‑Präfixes.

Beziehungen: Adjazenzlisten und Many‑to‑Many

Für graphartige Beziehungen funktioniert eine Adjazenzliste gut: speichere Kanten als Items.

  • PK = USER#123, SK = FOLLOWS#USER#456

Für Reverse‑Lookups oder echte Many‑to‑Many füge ein invertiertes Edge‑Item hinzu oder projiziere auf eine GSI, je nach benötigten Lesewegen.

Zeitreihen: Bucket + Sort Key + TTL

Für Events und Metriken vermeide unbegrenzte Partitionen durch Bucketing:

  • PK = DEVICE#9#2025-12-22 (Device + Tag)
  • SK = TS#1734825600 (Timestamp)

Verwende TTL, um alte Punkte automatisch zu entfernen, und halte Aggregate (stündlich/täglich) als separate Items für schnelle Dashboards.

Wenn du eine tiefere Auffrischung zu Key‑Konventionen willst, siehe /blog/partition-key-and-sort-key-design.

Streams und ereignisgesteuerte Architekturen

DynamoDB Streams ist Dynamos Änderungserfassungsfeed (CDC). Wenn auf einer Tabelle aktiviert, erzeugt jeder Insert, Update oder Delete einen Stream‑Record, auf den Downstream‑Consumer reagieren können—ohne die Tabelle zu pollern.

Grundlagen der DynamoDB Streams

Ein Stream‑Record enthält Keys und (optional) alte und/oder neue Images des Items, abhängig vom gewählten Stream View Type (Keys only, New image, Old image, Both). Records sind in Shards gruppiert, die sequentiell gelesen werden.

Aufbau ereignisgesteuerter Workflows

Ein häufiges Setup ist DynamoDB Streams → AWS Lambda, wobei jede Batch von Records eine Funktion auslöst. Andere Consumer sind ebenfalls möglich (kundenspezifische Consumer oder Weiterleitung in Analytics/Logging‑Systeme).

Typische Workflows umfassen:

  • Materialisierte Sichten: schreibe ein denormalisiertes Read‑Model, wenn sich die Quelltabelle ändert.
  • Cache‑Invalidation: lösche oder aktualisiere Items in Redis/ElastiCache nach Writes.
  • Audit‑Logs: hänge unveränderliche Änderungsereignisse an eine Audit‑Tabelle oder externen Store an.

Das hält die Primärtabelle für niedrig-latente Reads/Writes optimiert, während abgeleitete Arbeit asynchron erfolgt.

Reihenfolge, Retries und Korrektheit

Streams garantieren geordnetes Verarbeiten pro Shard (was typischerweise mit dem Partition Key korreliert), aber keine globale Reihenfolge über alle Keys. Die Zustellung ist mindestens einmal, daher können Duplikate auftreten.

Zum sicheren Umgang:

  • Mache Handler idempotent (z. B. Upsert per Primärschlüssel, bedingte Writes oder Speicherung verarbeiteter Event‑IDs).
  • Erwarte Retries und partielle Batch‑Fehler; verwende DLQs/On‑Failure‑Ziele wo möglich.
  • Halte Seiteneffekte (E‑Mails, Zahlungen) hinter Deduplikation oder transaktionalen Absicherungen.

Mit diesen Garantien im Blick können Streams DynamoDB zu einem soliden Rückgrat für ereignisgesteuerte Systeme machen.

Zuverlässigkeit, Backups und Observability

DynamoDB ist auf hohe Verfügbarkeit ausgelegt, indem Daten über mehrere Availability Zones innerhalb einer Region verteilt werden. Für die meisten Teams ergeben sich die praktischen Zuverlässigkeitsgewinne aus einer klaren Backup‑Strategie, dem Verständnis von Replikationsoptionen und dem Monitoring der richtigen Metriken.

Backups: On‑Demand vs. Point‑in‑Time Recovery

On‑Demand‑Backups sind manuelle (oder automatisierte) Snapshots, die du für einen bekannten Wiederherstellungspunkt erstellst—vor einer Migration, nach einem Release oder vor einem großen Backfill. Sie eignen sich für „Bookmark“-Momente.

Point‑in‑Time Recovery (PITR) erfasst kontinuierlich Änderungen, sodass du die Tabelle auf einen beliebigen Zeitpunkt innerhalb des Aufbewahrungsfensters zurücksetzen kannst. PITR ist das Sicherheitsnetz gegen versehentliches Löschen, fehlerhafte Deploys oder schlecht formatierte Writes.

Replikation und Multi‑Region‑Optionen

Wenn du Multi‑Region‑Resilienz oder niedrige Latenz nahe bei Benutzern brauchst, replizieren Global Tables Daten über ausgewählte Regionen. Sie vereinfachen Failover‑Planung, bringen aber Cross‑Region‑Replikationsverzögerungen und Konfliktlösungsfragen mit sich—halte daher Schreibmuster und Item‑Ownership klar.

Monitoring‑Essentials

Mindestens solltest du Alerts für folgende Signale haben:

  • Latenz (p95/p99) für Reads und Writes
  • Throttled Requests und System Errors
  • Consumed Capacity (und Headroom gegenüber Provisioned)

Diese Signale zeigen typischerweise heiße Partitionen, unzureichende Kapazität oder unerwartete Zugriffsmuster an.

Incident‑Playbooks

Bei Throttling identifiziere zuerst das verursachende Zugriffsmuster, mindere dann kurzfristig, indem du auf On‑Demand wechselst oder Provisioned Capacity erhöhst, und überlege Sharding heißer Keys.

Bei partiellen Ausfällen oder erhöhten Fehlern reduziere die Blast Radius: deaktiviere nicht‑kritischen Traffic, retry mit jittered Backoff und falle (z. B. mit gecachten Reads) graceful zurück, bis die Tabelle stabil ist.

Sicherheit und Zugriffskontrolle

DynamoDB-App schnell prototypen
Per Chat einen DynamoDB-Service und die UI prototypen und Schlüssel anpassen, sobald reale Abfragen auftauchen.

DynamoDB‑Sicherheit dreht sich größtenteils darum, wer welche API‑Aktionen ausführen darf, von wo und auf welche Keys. Da Tabellen viele Entitätstypen (und manchmal mehrere Tenants) enthalten können, sollte Zugriffskontrolle zusammen mit dem Datenmodell entworfen werden.

IAM‑Berechtigungen: Least Privilege standardmäßig

Beginne mit identity‑basierten IAM‑Policies, die Aktionen einschränken (z. B. dynamodb:GetItem, Query, PutItem) auf das notwendige Minimum und auf spezifische Table‑ARNs begrenzen.

Für feingranularere Kontrolle nutze dynamodb:LeadingKeys, um Zugriff nach Partition Key Werten einzuschränken—nützlich, wenn ein Service oder Tenant nur seinen eigenen Keyspace lesen/schreiben soll.

Verschlüsselung: worauf prüfen

DynamoDB verschlüsselt Daten standardmäßig at rest mit AWS‑eigenen Keys oder einem customer‑managed KMS‑Key. Bei Compliance‑Anforderungen überprüfe:

  • Ob die Tabelle mit dem vorgesehenen KMS‑Key konfiguriert ist
  • Ob die aufrufende Rolle die notwendigen KMS‑Berechtigungen (und nichts Weiteres) hat

Für Verschlüsselung in Transit stelle sicher, dass Clients HTTPS verwenden (AWS SDKs tun dies standardmäßig). Wenn TLS in einem Proxy terminiert wird, bestätige, dass der Hop zwischen Proxy und DynamoDB weiterhin verschlüsselt ist.

Netzwerkkontrollen: Exfiltrationswege reduzieren

Nutze ein VPC Gateway Endpoint für DynamoDB, damit Traffic im AWS‑Netz bleibt und du Endpoint‑Policies anwenden kannst, um Zugriff einzuschränken. Kombiniere das mit Egress‑Kontrollen (NACLs, Security Groups und Routen), um „anything can reach the public internet“-Pfade zu vermeiden.

Multi‑Tenant‑Design und Isolationsmuster

Für Shared Tables füge eine Tenant‑Kennung in den Partition Key ein (z. B. TENANT#<id>) und erzwinge Tenant‑Isolation mit IAM‑Bedingungen auf dynamodb:LeadingKeys.

Wenn du stärkere Isolation brauchst, ziehe separate Tabellen pro Tenant oder Environment in Betracht; behalte Shared‑Table‑Designs nur dort, wo operative Einfachheit und Kosteneffizienz den größeren Blast‑Radius überwiegen.

Kostenoptimierung für DynamoDB

DynamoDB ist oft „günstig, wenn du präzise bist, teuer wenn du vage bist.“ Kosten folgen typischerweise deinen Zugriffsmustern, daher beginnt die beste Optimierung damit, diese Muster explizit zu machen.

Kenne die Kostentreiber

Deine Rechnung wird hauptsächlich geformt durch:

  • Reads und Writes (RCUs/WCUs im Provisioned‑Modus, Request Units im On‑Demand)
  • Storage (Tabellendaten plus Item‑Größe)
  • Sekundäre Indizes (jede GSI hat eigene Schreib‑ und Speicher‑Kosten)
  • Streams (Leseanfragen gegen Stream‑Records und alle Downstream‑Consumer)

Überraschend für viele: Jeder Schreibvorgang auf die Tabelle ist auch ein Schreibvorgang für jeden betroffenen GSI, also kann „noch ein Index“ die Schreibkosten multiplizieren.

Keys designen, um Verschwendung zu vermeiden

Gutes Key‑Design reduziert die Notwendigkeit teurer Operationen. Wenn du häufig zu Scan greifst, zahlst du dafür, Daten zu lesen, die du anschließend verwirfst.

Bevorzuge:

  • Query nach Partition Key (und optional Sort Key Bedingungen)
  • Enge Projektionen in deinen GSIs (projiziere nur benötigte Attribute)

Wenn ein Zugriffsmuster selten ist, erwäge, es über eine separate Tabelle, einen ETL‑Job oder ein gecachtes Read‑Model statt über einen permanenten GSI zu bedienen.

Speicher mit TTL und Lifecycle kontrollieren

Nutze TTL, um kurzlebige Items automatisch zu löschen (Sessions, temporäre Tokens, intermediate Workflow‑State). Das reduziert Storage und kann Indizes über die Zeit klein halten.

Bei append‑lastigen Daten (Events, Logs) kombiniere TTL mit Sort‑Key‑Designs, die Abfragen „nur die letzten“ erlauben, sodass du nicht routinemäßig kalte Historie berühren musst.

Kapazität richtig dimensionieren und versehentliche Spitzen vermeiden

Im Provisioned‑Modus setze konservative Baselines und skaliere mit Auto Scaling basierend auf realen Metriken. Im On‑Demand‑Modus überwache ineffiziente Muster (große Items, chatty Clients), die Anfragevolumen treiben.

Behandle Scan als letzte Option—wenn du wirklich Full‑Table‑Processing brauchst, plane es außerhalb der Spitzenzeiten oder führe es als kontrollierte Batch mit Pagination und Backoff aus.

Wann man DynamoDB wählen sollte (und wann nicht)

DynamoDB glänzt, wenn deine Anwendung als Menge wohldefinierter Zugriffsmuster ausgedrückt werden kann und du durchgängig niedrige Latenz bei großem Maßstab brauchst. Wenn du deine Reads und Writes im Voraus (nach Partition Key, Sort Key und wenigen Indizes) beschreiben kannst, ist es oft eine der einfachsten Möglichkeiten, einen hochverfügbaren Datenspeicher zu betreiben.

Gute Einsatzzwecke

DynamoDB ist eine starke Wahl bei:

  • Vorhersehbaren Abfragen (Nutzerprofil holen, Bestellungen eines Nutzers nach Zeit auflisten, Session by ID)
  • Hohem Schreibdurchsatz oder spikigen Lasten, die du nicht managen willst
  • Bedarf an horizontaler Skalierung ohne Serverbetrieb
  • Ereignisgesteuerten Designs, die Streams nutzen, um downstream Arbeit auszulösen

Wann andere Lösungen besser sind

Suche Alternativen, wenn deine Kernanforderungen beinhalten:

  • Komplexe Joins über viele Entitäten oder häufige Relationship Traversals
  • Ad‑hoc‑Abfragen und Analytics, die sich wöchentlich ändern (Group‑Bys, explorative Filter)
  • Starkes Full‑Text‑Search‑/Relevance‑Ranking ohne externen Index

Hybride Ansätze, die gut funktionieren

Viele Teams nutzen DynamoDB für „heiße“ operative Reads/Writes und ergänzen dann mit:

  • S3 + Athena für Analytics und historische Reports
  • OpenSearch (oder Ähnliches) für Volltextsuche und Faceting
  • Eine Cache‑Schicht, wenn bestimmte Keys extrem leseintensiv sind

Prototyping‑Hinweis: den Weg vom Modell zur App verkürzen

Wenn du Zugriffsmuster und Single‑Table‑Konventionen validierst, zählt Geschwindigkeit. Teams prototypen manchmal Service und UI in Koder.ai (eine Vibe‑Coding‑Plattform, die Web-, Server‑ und Mobile‑Apps aus Chat baut) und iterieren dann am DynamoDB‑Key‑Design, während reale Abfragepfade auftauchen. Auch wenn das Produktions‑Backend anders aussieht, helfen schnelle End‑to‑End‑Prototypen, welche Queries Query sein sollten vs. welche versehentlich teure Scans würden.

Kurze Entscheidungs‑Checkliste

Validiere: (1) deine Top‑Queries sind bekannt und key‑basiert, (2) Korrektheitsanforderungen passen zum Konsistenzmodell, (3) erwartete Item‑Größen und Wachstum sind verstanden, und (4) das Kostenmodell (On‑Demand vs. Provisioned + Autoscaling) passt zu deinem Budget.

FAQ

Was ist DynamoDB und wann ist es eine gute Wahl?

DynamoDB ist eine vollständig verwaltete NoSQL-Datenbank von AWS, die für konstant niedrige Latenz bei Lese-/Schreibzugriffen in sehr großem Maßstab ausgelegt ist. Teams setzen sie ein, wenn sie zugriffsbasierte Muster über Schlüssel (z. B. Nachschlagen per ID, Auflisten nach Eigentümer, Zeitbereichsabfragen) definieren können und keine eigene Datenbankinfrastruktur betreiben möchten.

Sie ist besonders verbreitet in Microservices, serverlosen Anwendungen und ereignisgesteuerten Systemen.

Was sind Tabellen, Items und Attribute in DynamoDB?

Eine Tabelle enthält Items (ähnlich Zeilen). Jedes Item ist eine flexible Menge von Attributen (ähnlich Spalten) und kann verschachtelte Daten enthalten.

DynamoDB eignet sich gut, wenn eine Anfrage typischerweise „die ganze Entität“ benötigt, weil Items Maps und Lists (JSON-ähnliche Strukturen) enthalten können.

Was ist der Unterschied zwischen einem einfachen Primärschlüssel und einem zusammengesetzten Primärschlüssel?

Ein Partition Key allein identifiziert ein Item eindeutig (einfacher Primärschlüssel). Ein Partition Key + Sort Key (zusammengesetzter Schlüssel) erlaubt es, dass mehrere Items denselben Partition Key teilen, aber durch den Sort Key eindeutig und geordnet sind.

Zusammengesetzte Schlüssel ermöglichen Muster wie:

  • „Alle Bestellungen eines Kunden“
  • „Ereignisse für ein Gerät zwischen Zeitstempeln"
Wann sollte ich Query vs Scan verwenden?

Verwende Query, wenn du den Partition Key (und optional eine Sort Key-Bedingung) angeben kannst. Das ist der schnelle, skalierbare Weg.

Verwende Scan nur, wenn du wirklich alles lesen musst; es durchsucht die gesamte Tabelle oder den Index und filtert danach, was in der Regel langsamer und teurer ist.

Wenn du häufig scannst, ist das ein Hinweis darauf, dass dein Schlüssel- oder Index-Design angepasst werden sollte.

Was sind GSIs und LSIs und wie wähle ich sie aus?

Sekundäre Indizes bieten alternative Abfragepfade.

  • GSI (Global Secondary Index): kann einen anderen Partition Key (und optionalen Sort Key) als die Basistabelle haben; kann nachträglich hinzugefügt werden.
  • LSI (Local Secondary Index): teilt denselben Partition Key wie die Basistabelle, benutzt aber einen anderen Sort Key; muss bei der Tabellenerstellung definiert werden.

Indizes erhöhen die Schreibkosten, weil Schreibvorgänge in die Indizes repliziert werden.

Wie wähle ich zwischen On-Demand und Provisioned Kapazität?

Wähle On-Demand, wenn der Traffic unvorhersehbar, spiky ist oder du Kapazitätsmanagement vermeiden willst. Du zahlst pro Anfrage.

Wähle Provisioned, wenn die Nutzung stabil/vorhersagbar ist und du die Kosten besser kontrollieren möchtest. Kombiniere es mit Auto Scaling, beachte aber, dass Provisioned nicht sofort auf plötzliche Spitzen reagiert.

Welche Konsistenzoptionen bietet DynamoDB und wann sind sie wichtig?

Standardmäßig sind Lesezugriffe eventuell konsistent, das heißt kurz nach einem Schreibvorgang kannst du veraltete Werte lesen.

Verwende stark konsistente Lesezugriffe (wenn verfügbar) für kritische Prüfungen, die unbedingt aktuell sein müssen, z. B. Autorisierungsprüfungen oder Workflow-Status-Transitions.

Für Korrektheit unter Nebenläufigkeit sind atomare Updates (z. B. bedingte Writes oder ADD) oft robuster als ein Lese-Modifizieren-Schreib-Loop.

Wann sollte ich DynamoDB-Transaktionen verwenden?

Transaktionen (TransactWriteItems, TransactGetItems) bieten ACID-Garantien über bis zu 25 Items.

Nutze sie, wenn du mehrere Items zusammen aktualisieren musst (z. B. Bestellung anlegen und Lager reservieren) oder Invarianten durchsetzen willst, die keine Zwischenzustände tolerieren. Sie verursachen höhere Kosten und erhöhte Latenz, daher nur für notwendige Flüsse einsetzen.

Was sind Hot Keys/Partitionen und wie kann ich sie vermeiden?

Hot-Partitionen entstehen, wenn zu viele Anfragen denselben Partition Key Wert (oder eine kleine Menge von Werten) treffen, was zu Throttling führt, obwohl die Tabelle insgesamt wenig ausgelastet ist.

Übliche Gegenmaßnahmen:

  • Wähle hoch-kardinalen Partition Keys
  • Führe Write-Sharding ein (kleine zufällige/Hash-Suffixe)
  • Verwende Zeit-Buckets für Zeitreihen
  • Implementiere Exponential Backoff mit Jitter bei Throttles
Wie unterstützen DynamoDB Streams ereignisgesteuerte Architekturen?

Aktiviere DynamoDB Streams, um ein Änderungsprotokoll für Inserts, Updates und Deletes zu erhalten. Ein typisches Muster ist Streams → Lambda, um downstream Arbeit auszulösen.

Wichtige Eigenschaften, die berücksichtigt werden müssen:

  • Reihenfolge gilt pro Shard (nicht global)
  • Lieferung ist mindestens einmal (Duplikate sind möglich)

Mache Verbraucher idempotent (z. B. Upsert nach Key, bedingte Writes oder Nachverfolgung verarbeiteter Event-IDs).

Related posts