DynamoDB 自适应容量
DynamoDB 把你的表铺到多个分区上,但你的流量很少铺得均匀。突发容量 和 自适应容量 是两个自动机制,阻止一个偏斜的工作负载被限流——直到它撞上一个硬限制。
什么是 DynamoDB 自适应容量?
DynamoDB 自适应容量是一种自动机制,它把未用的吞吐量挪向 ,这样一个偏斜的 key 就不会被限流,而表的其余部分还闲着。配合突发容量,它免费吸收尖峰和持续偏斜——但它没法把单个 key 推过分区上限。
- 突发容量 借给你最多 5 分钟(300 秒)的未用吞吐量,帮你扛过短暂的尖峰。它是一个缓冲, 不是你去调的特性。
- 自适应容量 为一个"热"分区自动抬高吞吐量——从你表其余部分的未用容量里抽——这样一个 偏斜的 key 就不会被限流。
- 它甚至会把一个热 item 隔离 到它自己的分区上,给单个 key 直到分区上限的 3,000 RCU / 1,000 WCU。
- 它不是无视 key 设计的许可证。 过了每分区上限,就再没地方可借了——一个真正的热 key 仍然被限流。
先了解分区上限
每个分区都被独立封顶:每秒 3,000 读取单元和 1,000 写入单元。那个限制是物理的,不是 预置的——在预置表和按需表上都成立。(AWS, 突发与自适应容量。)
从 SQL 过来,你按 总 服务器负载来推理。在 DynamoDB 里被限流的单位是 单个分区,而一个 偏斜的 key 可以在表 90% 闲着的时候熔毁。这就是两个机制都为之而存在的缺口。
突发容量吸收短暂尖峰
每当你没有完全用掉一个分区的吞吐量,DynamoDB 就把剩下的存起来。最多 300 秒 的那种未用 容量被留作储备,一次突然的突发可以把它抽干得比你的每秒速率通常允许的更快。
它是隐形且自动的。你没法给它定大小,DynamoDB 还可能悄悄把一部分花在自己的后台工作上。把它 当作给突发流量的垫子——绝不要当作你能据以规划的余量。
自适应容量给热分区加力
突发容量处理 短 尖峰。自适应容量 处理 持续的 偏斜。当一个分区跑得火热而它的邻居闲 着时,DynamoDB 把吞吐量挪向那个热的——直到表的总量和分区上限。
假设你跑一张车队遥测表,key 为 VEHICLE#<id>(partition)和 TS#<epoch>(sort)。一辆在
闪购区的送货车发出的 ping 是任何别的车的 10 倍。它的分区是热的;其他 200 辆车的分区几乎
闲着。
自适应容量注意到并抬高那一个分区的吞吐量,从冷分区的未用容量里抽。无配置、无成本、无预热—— 自 2019 年 5 月起这个加力实际上是即时的。(AWS 数据库博客, "DynamoDB 自适应容量如何适应不均匀的访问模式"。)
热车的分区需要 150 WCU,但它 100 WCU 的均摊份额会被限流;自适应容量从冷分区借来闲置的 WCU 把它补上。
隔离:当问题出在单个 item 上
偏斜不总是按 key 的——有时是 单个 item 白热化。如果不停的流量驱动一个 VEHICLE#HOT
item,DynamoDB 的 按热拆分 会重新平衡分区,让那个被频繁访问的 item 单独落地。
一旦被隔离,那个单一 item 的 key 就能拉满整个 分区上限:3,000 RCU 和 1,000 WCU。那是 单个 key 的绝对天花板——再没有更高的机制了。(AWS, Key range throughput exceeded。)
一个值得钉住的注意点:当表带有 Local Secondary Index 时,自适应容量 不会把一个 item 集合 跨分区拆分。一个 LSI 把集合绑在一个分区上——见 GSI vs LSI了解原因。
当自适应容量救不了你
这是陷阱。两个机制都是把吞吐量 挪来挪去;谁都不会创造出超过一个分区物理允许的量。
| 场景 | 突发 | 自适应 | 结果 |
|---|---|---|---|
| 短尖峰,表有余量 | 扛住它 | — | 不限流 |
| 持续偏斜,冷邻居 | — | 给热的加力 | 不限流 |
| 一个 item,< 3K RCU / 1K WCU | — | 隔离它 | 不限流 |
| 一个 item,**> 分区上限 | 很快抽干 | 顶到天花板 | 限流——需要重新设计** |
| 多个 key 同时变热,表已满 | 很快抽干 | 没有闲置的 | 限流——需要重新设计 |
如果单个 key 合理地需要每秒超过 1,000 次写入,没有任何自动机制能救你——你必须把负载铺到更多 key 上。
写入分片 是常见的修法:追加一个后缀(VEHICLE#HOT#0 … #9),让写入扇到多个分区,
然后把读取扇回来。
那次扇入本身就是一个要刻意建模的访问模式,就像你在 单表设计里规划一条查询路径那样——自适应容量买来的是时间,不是 key 设计上的免费通行证。
在你自己的表上看它
自适应容量从设计上就是隐形的,所以你通过一个症状来推理它:哪些 key 是热的。当你构建分片写入
路径时,表达式构建器为一个带后缀的 key 生成 PutItem
和 Query 语法。
要看一个 key 在你的数据里实际怎么分布,下载 DynoTable,在你假设自适应容量已经 搞定它之前,先检查你真实表上的分区铺开情况。关于偏斜的读取一侧,见 Query vs Scan。