DynamoDB 批次操作
當你需要一次讀取或寫入許多項目時,每個項目觸發一次 GetItem 或 PutItem
意味著每個項目一次網路往返 —— 慢,且囉嗦。DynamoDB 的批次
API 把許多項目操作摺疊進一個單一請求:BatchGetItem 用於讀取,
BatchWriteItem 用於寫入。
它們是吞吐量與延遲上的勝利,而非一致性保證 —— 而那個 區別正是人們栽跟頭的地方。批次不是事務。
什麼是 DynamoDB 批次操作?
DynamoDB 批次操作把許多項目的讀或寫摺疊進一個單一請求:BatchGetItem 獲取最多 100 個項目,BatchWriteItem 放入或刪除最多 25 個,各自上限為 16 MB。它們節省往返,而非容量。關鍵在於,批次不是事務 —— 各個項目獨立地成功或失敗,沒有回滾。
BatchGetItem—— 在一次呼叫中跨一個或多個表獲取多達 100 個項目 (或 16 MB)。BatchWriteItem—— 在一次呼叫中進行多達 25 個 put/delete 操作(或 16 MB)。 沒有更新 —— 只有 put 和 delete。- 不是原子的。 個別項目可以成功而其他失敗。沒有回滾。
- 部分失敗是正常的。 被限流的項目會回到
UnprocessedItems/UnprocessedKeys裡 —— 你必須自己帶退避地重試它們。 - 與逐個呼叫相同的容量成本 —— 批次節省往返,而非容量 單元。
問題:許多項目,一次往返
假設你營運一個支援臺。一個儀表盤需要按 ID 載入 50 張工單來渲染一個 佇列;一個夜間作業歸檔 1,000 張已解決的工單。一次一個項目地做那件事 就是 50(或 1,000)次順序往返 —— 延遲層層累加,作業慢如爬行。
批次把那些摺疊成寥寥幾次呼叫。50 張工單的讀取變成一次
BatchGetItem;歸檔作業變成一連串每次 25 個刪除的
BatchWriteItem 呼叫。往返次數少得多,搬動的資料一樣多。
批次 API 如何工作
BatchGetItem 接受一組主索引鍵(跨一個或多個表)並返回
匹配的項目。你可以按表請求強一致讀取。它讀不到的任何東西 ——
通常是因為請求擦碰到了吞吐量限制 —— 會回到
UnprocessedKeys 裡,而非讓整個呼叫失敗。
BatchWriteItem 接受一個 PutRequest / DeleteRequest 操作列表。注意
缺了什麼:沒有更新。一次批寫要麼替換整個項目
(put),要麼移除它(delete) —— 要修改特定屬性,你仍需
UpdateItem。它寫不了的項目會回到 UnprocessedItems 裡。
關鍵心智模型:批次是一捆獨立的操作,每個 自行成功或失敗 —— 而非一個全有或全無的單元。
批次不是事務
這就是陷阱。如果你的歸檔作業的批次在中途撞上吞吐量限制,一些 工單被刪除了而一些沒有 —— 且 DynamoDB 不會撤銷那些已經 透過的。沒有回滾、沒有隔離、沒有“25 個全部或一個都不”。
如果你需要全有或全無的語義 —— “把工單移到已歸檔 並且 遞減
未結工單計數器,或者兩者都不做” —— 那是
TransactWriteItems,而非批次。事務成本
更高(每個操作按雙倍計費)且上限為 100 個項目,但它們給你
批次刻意不提供的原子性。
處理未處理項
一個正確的批次呼叫者總是檢查未處理集合並重試它。DynamoDB
在請求整體被接受但某些項目無法被服務時返回
UnprocessedItems/UnprocessedKeys —— 通常是短暫的限流。
只重新提交未處理的項目,帶 指數退避與抖動。 把批次當作即發即忘會靜默地丟失寫入 —— 那種 數月後才浮現為資料缺失的 bug。
DynoTable 裡的批寫
先用 DynamoDB 定價計算器估算一個批次 作業會花多少錢 —— 一個批次消耗的容量與它捆綁的 逐個寫入相同,只是請求次數更少。
在 DynoTable 裡,你在本地暫存你的編輯,並在提交它們之前審查它們 —— 跨許多行的批次更改會作為分組請求發出,而非每次一個 API 呼叫。批次刪除作為批寫發出,且未處理項的重試已為你 處理好。

陷阱與後續步驟
- 總是帶退避地重試
UnprocessedItems/UnprocessedKeys—— 它們是 預期之內的,而非異常。 - 無部分失敗回滾。 需要原子性?使用 事務。
- 批寫裡沒有更新 ——
BatchWriteItem只做 put/delete;要更改 屬性請動用UpdateItem。 - 留意每次呼叫的上限 —— 25 個寫 / 100 個讀 / 16 MB。超出會讓整次呼叫以
ValidationException失敗 (BatchGetItem中條目過多、BatchWriteItem中)。為更大的 作業分頁;參見分頁。
想在不為重試迴圈寫指令碼的情況下執行批次讀寫? 下載 DynoTable,直接編輯你的表。
往返數學
序列 GetItem 呼叫會支付每跳延遲。 BatchGetItem 捆綁最多 100
鍵或每個請求 16 MB — 以先達到的限制為準。
| 圖案 | 按鍵 | 大約。往返@ 50 鍵 | 筆記 |
|---|---|---|---|
連續劇GetItem | 50 | 50 50 | 50最簡單的程式碼;最差尾部延遲 |
一個 BatchGetItem | 50 | 50 1 | RCU 總數與 50 次相同 |
| 兩批 | 120 | 120 2 | 第二批攜帶20把鑰匙 |
容量成本不變 — 批次節省了掛鐘時間和用戶端 CPU,而不是遠端控制單元。對於寫入,每批 25 次的 1,000 次刪除相當於 40 次 BatchWriteItem 呼叫而不是 1,000 個單獨刪除。
強一致批次讀取
請求對映中的每個表BatchGetItem接受ConsistentRead: true。對於相同項目,強讀取的成本仍然是最終讀取 RCU 的 2 倍。混合一次批次呼叫中一致且最終的表就可以了——每個表條目攜帶自己的旗幟。
分塊大型作業
當歸檔 1,000 個平均每個 3 KB 的項目時,單批讀取保持在 100 項上限,但可能超過 16 MB(100 × 3 KB = 300 KB — 安全)。存檔 50 KB 的項目,每次呼叫都會達到大約 320 個項目的兆位元組上限,即使計數限制為 100。頁面使用顯式迴圈寫入:
for each chunk of 25 keys:
BatchWriteItem
retry UnprocessedItems with backoff until emptyDynoTable的分階段提交批次符合條件的寫入並重試未處理的項目自動地——否則你會用不穩定的睡眠來編寫這種模式。
批次決策與事務決策
| 需要 | API | 最大物品數 | 關於部分失敗 |
|---|---|---|---|
| 盡力批次裝載 | BatchWriteItem | 25 次操作 | 重試未處理 |
| 全有或全無的賬本轉移 | TransactWriteItems | 100 次操作 | 整個 txn 回滾 |
| 閱讀許多已知的金鑰 | BatchGetItem | 100 個按鍵 | 重試未處理的金鑰 |
| 原子讀+寫 | TransactWriteItems | 25 次交易操作(有記錄的限制適用) | 全部或全部 |
使用以下命令從普通 JSON 生成放置/刪除有效負載 DynamoDB JSON converter 播種批次時來自固定裝置的負載。
檢查消耗的容量
根據請求,批次響應可以包含每個表 ConsumedCapacity。記錄它在回填期間 - 隨著未處理集的增加,節流率不斷上升在就業完全停滯之前。交叉檢查持續的 WCU 與
pricing calculator 如果批次執行在時間表。


