進階閱讀時間 3 分鐘

DynamoDB 自適應容量:能做什麼,不能做什麼

DynamoDB 把你的表格分散到多個 partition,但你的流量很少均勻分散。Burst capacityadaptive capacity 是兩個自動機制,能阻止一個傾斜的工作負載被節流——直到它撞上一個硬性上限。

什麼是 DynamoDB adaptive capacity?

DynamoDB adaptive capacity 是一個自動機制,它會把未使用的輸送量挪向一個 ,好讓一個傾斜的鍵在表格其餘部分閒置時不會被節流。搭配 burst capacity,它能免費吸收尖峰與持續的傾斜——但它無法把單一個鍵推過 partition 的天花板。

  • Burst capacity 借給你最多 5 分鐘(300 秒)的未使用輸送量,以撐過短暫的尖峰。它是一個緩衝,不是一個你去調校的功能。
  • Adaptive capacity 會自動為一個 提高輸送量——從你表格其餘的未使用容量中汲取——好讓一個傾斜的鍵不會被節流。
  • 它甚至會把一個熱門項目隔離到它自己的 partition 上,讓單一個鍵拿到最高達 partition 天花板的 3,000 RCU / 1,000 WCU。
  • 它不是可以無視鍵設計的許可證。 過了每個 partition 的天花板,就再無可借之處——一個真正的熱門鍵仍會被節流。

先弄懂 partition 的天花板

每個 partition 都被獨立封頂:每秒 3,000 個讀取單位與 1,000 個寫入單位。那個限制是實體的,不是佈建的——它在佈建與隨需表格上都成立。(AWS,Burst 與 adaptive capacity。)

從 SQL 過來,你推理的是_總體_伺服器負載。在 DynamoDB 中,會被節流的單位是單一 partition,而一個傾斜的鍵可能在表格坐擁 90% 閒置時就融毀。那正是這兩個機制存在要彌合的落差。

Burst capacity 吸收短暫的尖峰

每當你沒有完全用滿一個 partition 的輸送量,DynamoDB 就會把剩餘的存起來。這份未使用容量最多有 300 秒被保留在後備中,而一次突然的暴衝能把它耗盡得比你的每秒速率通常所允許的更快。

它是隱形且自動的。你無法設定它的大小,而 DynamoDB 可能會悄悄花掉其中一些在它自己的背景工作上。把它當成應付突發流量的一塊墊子——絕不要當成你可以拿來規劃的餘裕。

Adaptive capacity 為熱分割區加速

Burst capacity 處理_短暫的_尖峰。Adaptive capacity 處理_持續的_傾斜。當一個 partition 跑得火熱而它的鄰居閒置時,DynamoDB 會把輸送量挪向那個熱的——直到表格總量與 partition 天花板為止。

假設你跑一個車隊遙測表格,鍵為 VEHICLE#<id>(partition)與 TS#<epoch>(sort)。快閃銷售區裡的一台送貨廂型車,發出的 ping 量是其他任何一台的 10 倍。它的 partition 是熱的;其他 200 台廂型車的 partition 幾乎閒置。

Adaptive capacity 會注意到,並拉高那一個 partition 的輸送量,從冷 partition 的未使用容量中汲取。無需設定、無成本、無暖機——自 2019 年 5 月起,這個加速實際上是即時的。(AWS Database Blog,「How DynamoDB adaptive capacity accommodates uneven access patterns」。)

借出閒置 WCU借出閒置 WCU借出閒置 WCU表格:400 WCUVEHICLE#A1~50 WCU(冷)VEHICLE#B7~50 WCU(冷)VEHICLE#C3~50 WCU(冷)VEHICLE#HOT150 WCU(熱)

那台熱門廂型車的 partition 需要 150 WCU,但它平均分到的 100 WCU 份額會被節流;adaptive capacity 從冷 partition 借來閒置的 WCU 來補足。

隔離:當問題出在單一項目時

傾斜不總是逐鍵的——有時是_單一個項目_白熱化。如果不停歇的流量猛打一個 VEHICLE#HOT 項目,DynamoDB 的熱點分裂(split-for-heat)會重新平衡各 partition,好讓那個被頻繁存取的項目獨自落地。

一旦被隔離,那單一個項目的鍵就能拉到完整的 partition 天花板:3,000 RCU 與 1,000 WCU。那是單一個鍵的絕對頂點——之上再無任何機制。(AWS,Key range throughput exceeded。)

有一個值得釘住的但書:當表格有一個 時,adaptive capacity 不會把一個 跨 partition 分裂。一個 LSI 會把項目集合綁定到一個 partition——原因參見 GSI 與 LSI

當 adaptive capacity 救不了你

這是陷阱。這兩個機制都是把輸送量_挪來挪去_;兩者都不會創造出多過一個 partition 實體所允許的量。

情境BurstAdaptive結果
短暫尖峰、表格有餘裕涵蓋它不節流
持續傾斜、鄰居是冷的為熱的加速不節流
單一項目、< 3K RCU / 1K WCU隔離它不節流
單一項目、> partition 天花板迅速耗盡已在頂點被節流——需要重新設計
一次多個鍵皆熱、表格已滿迅速耗盡無閒置可挪被節流——需要重新設計

如果一個單一鍵正當地需要每秒超過 1,000 次寫入,沒有任何自動機制能救你——你必須把負載分散到更多的鍵上。

寫入分片(write sharding)是常見的解法:附上一個後綴(VEHICLE#HOT#0#9),讓寫入扇出到多個 partition,然後在讀取時把它們扇入。

那個扇入本身就是一個要刻意去建模的存取模式,就像你在 單表設計 中規劃一條查詢路徑那樣——adaptive capacity 買到的是時間,不是可以在鍵設計上放行的通行證。

在你自己的表格上看看它

Adaptive capacity 天生就是隱形的,所以你透過一個症狀來推理它:哪些鍵是熱的。當你建置分片寫入路徑時,運算式建構器 會為一個帶後綴的鍵產生 PutItemQuery 語法。

要觀察一個鍵實際上如何在你的資料上分布,下載 DynoTable,在 SQL Workbench 中對你的 partition key 執行一個 GROUP BY,看看在你假設 adaptive capacity 已經搞定之前,各鍵的項目是怎麼堆疊的。關於傾斜的讀取面,參見 Query 與 Scan

已更新