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 如果批次运行在时间表。


