DynamoDB 批次操作:BatchGetItem 與 BatchWriteItem
當你需要一次讀取或寫入許多項目時,對每個項目各發一次 GetItem 或 PutItem,意味著每個項目一次網路往返 — 既慢又囉嗦。DynamoDB 的批次 API 把許多項目操作摺進單一請求裡:讀取用 BatchGetItem,寫入用 BatchWriteItem。
它們是輸送量與延遲上的勝利,不是一致性保證 — 而人們正是在這個區別上栽跟頭。一個批次不是一筆交易。
什麼是 DynamoDB 批次操作?
DynamoDB 批次操作把許多項目讀取或寫入摺進單一請求:BatchGetItem 一次擷取多達 100 個項目,BatchWriteItem 一次 put 或 delete 多達 25 個,兩者各以 16 MB 為上限。它們省下的是往返,不是容量。關鍵在於,一個批次不是一筆交易 — 個別項目各自成功或失敗,沒有 rollback。
BatchGetItem— 在一次呼叫裡,橫跨一張或多張表,擷取多達 100 個項目(或 16 MB)。BatchWriteItem— 在一次呼叫裡,多達 25 個 put/delete 操作(或 16 MB)。沒有 update — 只有 put 與 delete。- 不是原子的。 個別項目可能成功而其他失敗。沒有 rollback。
- 部分失敗是常態。 被節流的項目會回到
UnprocessedItems/UnprocessedKeys— 你必須自己重試它們,並搭配退避。 - 與個別呼叫相同的容量成本 — 批次省下的是往返,不是容量單位。
問題:許多項目,一次往返
假設你經營一個客服台。一個儀表板需要依 ID 載入 50 張工單來繪製一個佇列;一個過夜的工作要封存 1,000 張已解決的工單。一次一個項目地做那件事,就是 50(或 1,000)次連續往返 — 延遲層層堆疊,工作爬行般地慢。
批次把那些摺成寥寥幾次呼叫。讀 50 張工單變成一次 BatchGetItem;封存工作變成一連串各含 25 個 delete 的 BatchWriteItem 呼叫。往返次數少得多,搬移的資料一樣。
批次 API 如何運作
BatchGetItem 取一組主鍵(橫跨一張或多張表)並回傳相符的項目。你可以對每張表請求強一致讀取。任何它讀不到的 — 通常是因為請求擦到了一個輸送量上限 — 會回到 UnprocessedKeys,而不是讓整個呼叫失敗。
BatchWriteItem 取一個 PutRequest / DeleteRequest 操作的串列。注意少了什麼:沒有 update。一個批次寫入要嘛替換一整個項目(put)、要嘛移除它(delete) — 要修改特定屬性,你仍需要 UpdateItem。它寫不了的項目會回到 UnprocessedItems。
關鍵的心智模型:一個批次是一束獨立的操作,各自成功或失敗 — 不是一個全有或全無的單元。
批次不是交易
這就是那個陷阱。如果你封存工作的批次在半途撞到一個輸送量上限,有些工單被刪了、有些沒有 — 而 DynamoDB 不會還原那些已經通過的。沒有 rollback、沒有隔離、沒有「25 個全部或一個都不」。
如果你需要全有或全無的語意 —「把工單移到已封存,而且把開啟工單的計數器減一,否則兩者都不做」— 那是 TransactWriteItems,不是批次。交易花費更多(每個操作的計費加倍)且上限為 100 個項目,但它們給你批次刻意不給的那種原子性。
處理未處理的項目
一個正確的批次呼叫者總是檢查那組未處理項目並重試它。每當請求作為整體被接受、但有些項目無法被服務時 — 典型是暫時性的節流 — DynamoDB 就會回傳 UnprocessedItems/UnprocessedKeys。
只重新提交那些未處理的項目,並搭配指數退避與抖動。把一個批次當成射後不理,會無聲地丟掉寫入 — 那種幾個月後才以遺失資料浮現的 bug。
在 DynoTable 中的批次寫入
先用DynamoDB 定價計算機估算一個批量工作的成本 — 一個批次消耗的容量與它所打包的個別寫入相同,只是所用的請求數更少。
在 DynoTable 中,你在本機暫存編輯,並在把它們以高效的批次寫入提交之前先行審閱 — 橫跨許多列的批量變更,是以分組請求送出,而不是每次變更各發一次 API 呼叫,且未處理項目的重試已替你處理好。

陷阱與下一步
- 總是重試
UnprocessedItems/UnprocessedKeys,並搭配退避 — 它們是預期之內,而非例外。 - 沒有部分失敗的 rollback。 需要原子性?用交易。
- 批次寫入裡沒有 update —
BatchWriteItem只有 put/delete;要改屬性,動用UpdateItem。 - 留意每次呼叫的上限 — 25 筆寫入 / 100 筆讀取 / 16 MB。較大的工作要分頁;請見分頁。
想在不為重試迴圈寫腳本的情況下,跑批量讀寫嗎?下載 DynoTable,直接編輯你的表格。


