DynamoDB 批处理操作:BatchGetItem 与 BatchWriteItem
当你需要一次读取或写入许多项时,为每个项各发一次 GetItem 或 PutItem,就意味着每个项一次
网络往返 —— 既慢又啰嗦。DynamoDB 的批处理 API 把许多项操作折叠进一个请求:读取用
BatchGetItem,写入用 BatchWriteItem。
它们是吞吐量与延迟上的胜利,而不是一致性保证 —— 而正是这个区分让人栽跟头。一个批处理不是 事务。
什么是 DynamoDB 批处理操作?
DynamoDB 批处理操作把许多项的读取或写入折叠进一个请求:BatchGetItem 至多取回 100 个项,BatchWriteItem 至多 put 或 delete 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;归档任务变成一串
BatchWriteItem 调用,每次 25 个 delete。往返少得多,搬动的数据却一样。
批处理 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。更大的任务要分页; 参见分页。
想做批量读写却不必手写重试循环? 下载 DynoTable,直接编辑你的表。


