Fortgeschritten7 Min. Lesezeit

DynamoDB-Batch-Operationen

Wenn du viele Items auf einmal lesen oder schreiben musst, pro Item ein GetItem oder PutItem zu feuern heißt ein Network Round Trip pro Item — langsam und gesprächig. DynamoDBs Batch-APIs falten viele Item-Operationen in einen einzelnen Request: BatchGetItem für Reads, BatchWriteItem für Writes.

Sie sind ein Throughput-und-Latency-Win, keine Consistency-Garantie — und diese Unterscheidung ist, wo Leute verbrennen. Ein Batch ist keine Transaction.

Was sind DynamoDB-Batch-Operationen?

DynamoDB-Batch-Operationen falten viele Item-Reads oder -Writes in einen einzelnen Request: BatchGetItem holt bis zu 100 Items, BatchWriteItem puttet oder löscht bis zu 25, jeweils capped bei 16 MB. Sie sparen Round Trips, nicht Capacity. Kritisch: ein Batch ist keine Transaction — Items succeeden oder failen unabhängig, ohne Rollback.

  • BatchGetItem — bis zu 100 Items (oder 16 MB) über eine oder mehrere Tabellen in einem Call fetchen.
  • BatchWriteItem — bis zu 25 Put/Delete-Operationen (oder 16 MB) in einem Call. Keine Updates — nur Puts und Deletes.
  • Nicht atomar. Einzelne Items können succeeden, während andere failen. Es gibt kein Rollback.
  • Partial Failure ist normal. Gedrosselte Items kommen in UnprocessedItems / UnprocessedKeys zurück — du musst sie selbst retryen, mit Backoff.
  • Dieselben Capacity-Kosten wie die einzelnen Calls — Batching spart Round Trips, nicht Capacity Units.

Das Problem: viele Items, ein Round Trip

Angenommen, du betreibst einen Support-Desk. Ein Dashboard muss 50 Tickets per ID laden, um eine Queue zu rendern; ein Overnight-Job archiviert 1.000 resolved Tickets. Das Item für Item zu tun sind 50 (oder 1.000) sequenzielle Round Trips — Latenz stapelt sich und der Job kriecht.

Batching kollabiert das in eine Handvoll Calls. Der 50-Ticket-Read wird ein einzelnes BatchGetItem; der Archive-Job wird ein Stream von BatchWriteItem- Calls à 25 Deletes. Weit weniger Round Trips, dieselben Daten bewegt.

Wie die Batch-APIs arbeiten

BatchGetItem nimmt eine Menge Primary Keys (über eine oder mehrere Tabellen) und gibt die matchenden Items zurück. Du kannst stark konsistente Reads pro Tabelle anfordern. Was es nicht lesen konnte — meist weil der Request ein Throughput-Limit streifte — kommt in UnprocessedKeys zurück, statt den ganzen Call zu failen.

BatchWriteItem nimmt eine Liste von PutRequest-/DeleteRequest-Operationen. Beachtee, was fehlt: es gibt kein Update. Ein Batch-Write ersetzt entweder ein ganzes Item (Put) oder entfernt es (Delete) — um spezifische Attribute zu ändern, brauchst du weiterhin UpdateItem. Items, die er nicht schreiben konnte, kommen in UnprocessedItems zurück.

succeededthrottledRetry mit BackoffBatchWriteItem: 25 Puts/DeletesPer-Item-ProcessingGeschriebenUnprocessedItems

Ein Batch ist ein Bündel unabhängiger Operationen, die jeweils für sich succeeden oder failen — keine All-or-Nothing-Einheit.

Batches sind keine Transactions

Das ist die Falle. Wenn der Batch deines Archive-Jobs halbwegs ein Throughput- Limit trifft, sind manche Tickets gelöscht und manche nicht — und DynamoDB macht die, die durchgingen, nicht rückgängig. Kein Rollback, keine Isolation, kein „alle 25 oder keines“.

Brauchst du All-or-Nothing-Semantik — „beweg das Ticket nach archived und decrementiere den Open-Tickets-Counter, oder tu keines“ — das ist TransactWriteItems, kein Batch. Transactions kosten mehr (jede Operation wird doppelt abgerechnet) und capen bei 100 Items, geben dir aber die Atomicity, die Batches bewusst nicht geben.

Unprocessed Items handhaben

Ein korrekter Batch-Caller prüft immer das Unprocessed-Set und retryt es. DynamoDB gibt UnprocessedItems/UnprocessedKeys zurück, wann immer der Request als Ganzes akzeptiert wurde, aber manche Items nicht bedient werden konnten — typischerweise transient Throttling.

Re-submitte nur die unprocessed Items, mit exponential Backoff und Jitter. Einen Batch als Fire-and-Forget zu behandeln droppt Writes still — die Art Bug, die Monate später als fehlende Daten auftaucht.

Batch-Writes in DynoTable

Schätze zuerst, was ein Bulk-Job kostet, mit dem DynamoDB Pricing Calculator — ein Batch verbraucht dieselbe Capacity wie die einzelnen Writes, die er bündelt, nur in weniger Requests.

In DynoTable stagest du Edits lokal und reviewst sie vor dem Commit — Bulk- Änderungen über viele Rows gehen als gruppierte Requests raus statt als ein API- Call je. Bulk-Deletes gehen als batched Writes raus, mit dem Unprocessed-Item- Retry für dich gehandelt.

Gestaged Edits reviewen, bevor sie als Batch in DynoTable committen.
Gestaged Edits reviewen, bevor sie als Batch in DynoTable committen.

Fallstricke + nächste Schritte

  • Retrye UnprocessedItems/UnprocessedKeys immer mit Backoff — sie sind erwartet, nicht exceptional.
  • Kein Partial-Failure-Rollback. Brauchst du Atomicity? Nutze Transactions.
  • Keine Updates in einem Batch-WriteBatchWriteItem ist Put/Delete only; greif zu UpdateItem, um Attribute zu ändern.
  • Achte auf die Per-Call-Caps — 25 Writes / 100 Reads / 16 MB. Sie zu überschreiten failt den ganzen Call mit ValidationException (zu viele Items in BatchGetItem, in BatchWriteItem). Page durch größere Jobs; siehe Pagination.

Willst du Bulk-Reads und -Writes fahren, ohne die Retry-Loop zu scripten? Lade DynoTable herunter und editiere deine Tabellen direkt.

Round-Trip-Mathe

Serielle GetItem-Calls zahlen Latenz pro Hop. BatchGetItem bündelt bis zu 100 Keys oder 16 MB pro Request — welches Limit zuerst trifft.

PatternKeysCa. Round Trips @ 50 KeysNotes
Serielles GetItem5050Einfachster Code; schlechteste Tail-Latenz
Ein BatchGetItem501Dieselbe RCU-Summe wie 50 Gets
Zwei Batches1202Zweiter Batch trägt 20 Keys

Capacity-Kosten sind unverändert — Batching spart Wall-Clock-Zeit und Client-CPU, nicht RCU. Für Writes sind 1.000 Deletes à 25 pro Batch 40 BatchWriteItem-Calls statt 1.000 einzelner Deletes.

Stark konsistente Batch-Reads

BatchGetItem akzeptiert ConsistentRead: true pro Tabelle in der Request-Map. Strong Reads kosten weiterhin 2× die RCU eventueller Reads für dieselben Items. Consistent und eventual Tabellen in einem Batch-Call zu mischen ist fine — jeder Table-Entry trägt sein eigenes Flag.

Große Jobs chunking

Beim Archivieren von 1.000 Items à durchschnittlich 3 KB bleibt ein einzelner Batch- Read unter dem 100-Item-Cap, kann aber 16 MB überschreiten (100 × 3 KB = 300 KB — safe). Archive 50-KB-Items und du triffst das Megabyte-Cap bei etwa 320 Items pro Call, obwohl das Count-Limit 100 ist.

Page Writes mit expliziten Loops:

for each chunk of 25 keys:
  BatchWriteItem
  retry UnprocessedItems with backoff until empty

DynoTables staged Commit batcht eligible Writes und retryt unprocessed Items automatisch — das Pattern, das du sonst mit jittered Sleep scripten würdest.

Batch vs Transaction Decision

NeedAPIMax ItemsBei Partial Failure
Best-effort Bulk LoadBatchWriteItem25 OpsUnprocessed retryen
All-or-nothing Ledger MoveTransactWriteItems100 OpsGanze Txn rollt zurück
Viele bekannte Keys lesenBatchGetItem100 KeysUnprocessed Keys retryen
Read + Write atomarTransactWriteItems25 Transact Ops (documented Limits gelten)All or none

Generiere Put/Delete-Payloads aus plainem JSON mit dem DynamoDB JSON Converter, wenn du Batch-Loads aus Fixtures seedest.

Consumed Capacity inspizieren

Batch-Responses können ConsumedCapacity pro Tabelle enthalten, wenn angefordert. Logge sie während Backfills — eine steigende Throttle-Rate zeigt sich als wachsende Unprocessed-Sets, bevor Jobs komplett stallieren. Cross-checke sustained WCU mit dem Pricing Calculator, wenn Batches nach Schedule laufen.

Aktualisiert