高级阅读约 3 分钟

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 自适应容量如何适应不均匀的访问模式"。)

借出闲置 WCU借出闲置 WCU借出闲置 WCU表:400 WCUVEHICLE#A1~50 WCU(冷)VEHICLE#B7~50 WCU(冷)VEHICLE#C3~50 WCU(冷)VEHICLE#HOT150 WCU(热)

热车的分区需要 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 生成 PutItemQuery 语法。

要看一个 key 在你的数据里实际怎么分布,下载 DynoTable,在你假设自适应容量已经 搞定它之前,先检查你真实表上的分区铺开情况。关于偏斜的读取一侧,见 Query vs Scan

更新于