DynamoDB 自适应容量:能做什么,不能做什么
DynamoDB 把你的表分散到各个分区,但你的流量很少均匀分布。突增容量和自适应容量是两种自动机制,它们阻止倾斜的工作负载被限流 —— 直到它撞上一个硬限制。
什么是 DynamoDB 自适应容量?
DynamoDB 自适应容量是一种自动机制,它把未使用的吞吐量转移到,这样一个倾斜的键就不会在表的其余部分闲置时被限流。与突增容量搭配,它能免费吸收峰值和持续倾斜 —— 但它无法把单个键推过分区上限。
- 突增容量借给你最多 5 分钟(300 秒)的未使用吞吐量,以度过短暂峰值。它是一个缓冲,而非你可调节的功能。
- 自适应容量为自动提升吞吐量 —— 从表其余部分的未使用容量中提取 —— 这样倾斜的键就不会被限流。
- 它甚至会隔离一个热点项目到它自己的分区上,给单个键最高至分区上限的 3,000 RCU / 1,000 WCU。
- 它不是无视键设计的许可证。 超过每分区上限后就无处可借了 —— 一个真正过热的键仍会被限流。
先了解分区上限
每个分区都被独立地限定上限:每秒 3,000 个读取单元和 1,000 个写入单元。那个限制是物理的,而非预置的 —— 它对预置表和按需表都成立。(AWS,突增与自适应容量。)
从 SQL 过来时,你会以 总 服务器负载来推理。在 DynamoDB 里,会被限流的单元是单个分区,一个倾斜的键可能在表 90% 都闲置时崩溃。那正是两种机制存在的意义所在,就是要弥合这个差距。
突增容量吸收短暂峰值
每当你没有完全用满一个分区的吞吐量时,DynamoDB 就会把剩余的存起来。最多 300 秒 的那份未使用容量会被留作储备,而一次突然的爆发可以比你的每秒速率通常允许的更快地将其抽干。
它是不可见且自动的。你无法为它设定大小,且 DynamoDB 可能悄悄地把其中一部分花在它自己的后台工作上。把它当作应对突发流量的缓冲垫 —— 绝不要当作你可以据以规划的余量。
自适应容量为热分区增能
突增容量处理 短暂 峰值。自适应容量处理 持续 倾斜。当一个分区过热而它的邻居们闲置时,DynamoDB 会把吞吐量转移到那个热分区 —— 最高至表的总量和分区上限。
假设你运行一张车队遥测表,键为 VEHICLE#<id>(分区)和 TS#<epoch>(排序)。一辆处于闪购区的送货货车发出的心跳是其他任何一辆的 10 倍。它的分区过热了;而其他 200 辆货车的分区几乎闲置。
自适应容量察觉到并提升那一个分区的吞吐量,从冷分区的未使用容量中提取。无需配置、无成本、无预热 —— 自 2019 年 5 月起,这种增能实际上是即时的。(AWS Database Blog,《DynamoDB 自适应容量如何适应不均匀的访问模式》。)
那辆热货车的分区需要 150 WCU,但它 100-WCU 的均分份额会被限流;自适应容量从冷分区借来闲置的 WCU 以覆盖它。
隔离:当问题出在单个项目
倾斜并不总是按键的 —— 有时是 单个项目 白热化。如果不停的流量驱动一个 VEHICLE#HOT 项目,DynamoDB 的按热度切分会重新平衡分区,使那个被频繁访问的项目单独落到一个分区上。
一旦被隔离,那个单一项目的键就能拉满整个分区上限:3,000 RCU 和 1,000 WCU。那是单个键的绝对天花板 —— 它之上再无任何机制。(AWS,键范围吞吐量已超出。)
有一个值得钉住的注意点:当表带有时,自适应容量不会把一个跨分区切分。LSI 会把该集合绑定到一个分区上 —— 参见 GSI 与 LSI 了解原因。
自适应容量救不了你的时候
这就是陷阱。两种机制都只是把吞吐量搬 来搬去;两者都无法创造出超过分区物理允许的量。
| 场景 | 突增 | 自适应 | 结果 |
|---|---|---|---|
| 短暂峰值,表有余量 | 覆盖它 | — | 不限流 |
| 持续倾斜,冷邻居 | — | 为热分区增能 | 不限流 |
| 单个项目,< 3K RCU / 1K WCU | — | 隔离它 | 不限流 |
| 单个项目,> 分区上限 | 迅速抽干 | 已到天花板 | 被限流 —— 需要重新设计 |
| 多个键同时过热,表已满 | 迅速抽干 | 无闲置可用 | 被限流 —— 需要重新设计 |
如果单个键确实合理地需要每秒超过 1,000 次写入,没有任何自动机制能救你 —— 你必须把负载分散到更多的键上。
写入分片是通常的解法:追加一个后缀(VEHICLE#HOT#0 … #9),使写入扇出到多个分区,然后在读取时把它们扇入合并。
那个扇入本身就是一种需要刻意建模的访问模式,就像你在单表设计里规划一条查询路径那样 —— 自适应容量买来的是时间,而不是键设计上的免费通行证。
在你自己的表上看到它
自适应容量在设计上是不可见的,因此你要通过一个症状来推理它:哪些键是热的。当你构建分片写入路径时,表达式构建器会为带后缀的键生成 PutItem 和 Query 语法。
要观察一个键在你数据中的实际分布情况,下载 DynoTable,在 SQL Workbench 里对你的分区键运行一次 GROUP BY,看看在你假定自适应容量已经搞定之前,各个键下的项目是如何堆积的。至于倾斜的读取侧,参见 Query 与 Scan。