上級読了 3 分

DynamoDB の物理パーティション

物理パーティションは、DynamoDB が実際にデータを格納する単位です。SSD の一切れで、 アベイラビリティゾーンをまたいでレプリケートされ、キー空間の一切れを保持します。テーブルは 論理的なものです。バイト——そしてスループットの上限——が本当に宿るのはパーティションです。

DynamoDB のパーティションはどう動きますか?

DynamoDB はテーブルを物理パーティションにまたがって格納します。アベイラビリティゾーンを またいでレプリケートされた SSD の一切れです。それぞれ約 10 GB、毎秒 3,000 読み取りユニット、 毎秒 1,000 書き込みユニットで頭打ちになります。の ハッシュがアイテムの落ちるパーティションを決め、DynamoDB はパーティションが成長したり ホットになったりすると自動的に分割します。

  • すべてのパーティションは約 10 GB のストレージ、毎秒 3,000 読み取りユニット、毎秒 1,000 書き込みユニットで頭打ちになる。 これらの上限はテーブルごとではなくパーティションごとです。
  • のハッシュがパーティションを選ぶ。 同じキーを 持つアイテムは一緒に落ちます。単一のホットな——あるいは 単調増加するソートキー——が1つのパーティションを釘付けにするものです。
  • DynamoDB はあなたの代わりにパーティションを分割する——サイズで、そして持続する熱で—— 1つのキーのアイテムコレクションをソートキーの境界で分割することも含みます。ただし LSI か 増え続けるソートキーがそれを妨げる場合を除きます。
  • キャパシティに余裕があるのにスロットリングするのが手がかり。 テーブルが 5% の使用率 なのに ProvisionedThroughputExceeded エラーが出るなら、単一のパーティションが上限に 達しています。

アイテムがパーティションを見つける仕方

DynamoDB は、パーティションキーの値を内部のハッシュ関数に通します。ハッシュの出力が物理 パーティションを選びます。同じキーを入れれば、同じパーティションが出てきます——毎回。

SQL から来ると、類似物はありません。チューニングするインデックスの B ツリーもなく、手で 割り当てるシャードキーもありません。配置は、あなたが制御せず、決して目にしないハッシュです。

パーティションキーを共有するアイテムはを 形成し、一緒に格納され、ソートキーでソートされます。それこそが、1つのキーへの Query を 安くするものです——1つのパーティション上の連続した1続きを読むのです。(Query vs Scan を参照。)

ゲームの試合イベントストアを取り上げます。テーブルのキーは arenaId (パーティション) と eventKey (ソート) です。

# Item
arenaId    = "ARENA#7f3a"
eventKey   = "EVT#1719100800#a91c"
playerTag  = "Nightjar"
dmgDealt   = 412

アリーナ 7f3a のすべてのイベントは同じパーティションにハッシュされ、ソートキー順に 積み重なります。「この試合のタイムラインを読む」には最高です。その1つのアリーナが すべてのトラフィックを集めるなら、それは負債です。

すべてのパーティションが強制する3つの上限

単一のパーティションは、最大でも以下を提供するように設計されています。

上限パーティションあたり数え方
ストレージ約 10 GB生のアイテムのバイト
読み取りキャパシティ毎秒 3,000 読み取りユニット1 RU = 1回の 4 KB の強い整合性のある読み取り
書き込みキャパシティ毎秒 1,000 書き込みユニット1 WU = 1回の 1 KB の書き込み

出典:AWS の パーティションキーを設計するためのベストプラクティス ガイド。

アイテムサイズが計算をスケールさせます。20 KB のアイテムは強い整合性のある読み取り1回に つき 5 読み取りユニットかかるので、1つのパーティションはスロットリングする前に毎秒約 600 回 そうした読み取りを提供します——3,000 ではありません。書き込みコストは 1 KB ごとに、読み取り コストは 4 KB ごとに切り上げます。

罠:これらは_パーティション_の上限であって、_テーブル_の上限ではありません。テーブルが 40,000 WCU にプロビジョンドされていても、すべての書き込みが 1,000 で頭打ちになる1つの パーティションを叩いていれば、スロットリングし得ます。

パーティションが分割される仕方

DynamoDB は2つの場合に自動的にパーティションを追加します。あなたがコマンドを実行することは 決してありません。

サイズによる分割。 パーティションが約 10 GB に向かって埋まると、DynamoDB はそのキー 範囲を2つに分割し、アイテムの半分を新しいパーティションに移します。ストレージは透過的に 成長し、その間ずっと読み取りと書き込みは動き続けます。

熱による分割。 パーティションがスループットの上限近くの持続的なトラフィックを受けると、 DynamoDB はホットなキー範囲を分割し、各半分が自分のパーティションに落ちるようにします。 AWS はこれをsplit-for-heat の仕組みと呼びます。自ずと止まる短いスロットリングの バーストは、しばしば split-for-heat が作動したことを意味します——ただし短いスパイクは 単にバーストキャパシティが枯れただけのこともあります。

サイズ負荷パーティション A~10 GB / ホット分割のトリガー?保存バイト数で範囲を二分トラフィックで範囲を二分2つのパーティションそれぞれ専用キャパシティ1つのホットなアイテムは依然1パーティション上

分割は多くのキーにまたがって余地を稼ぎ、split-for-heat は1つのキーのアイテムコレクション をソートキーの切れ目で切り分けることさえできます。それが広げられないのは、単一のホット アイテム、増え続けるソートキー、あるいは LSI に釘付けにされたコレクションです。

ホットキーが分割器に勝つ理由

ここが落とし穴です。分割はパーティションキーの_範囲_を再分配します。トラフィックが1つの キーの値に集中すると、すべてのリクエストが同じパーティションにハッシュされ、分割すべき 範囲が残りません。

アリーナ 7f3a がトーナメントの決勝で毎秒 4,000 書き込みを引く一方、他のすべての アリーナがアイドルなら、1,000 でスロットリングします——そして split-for-heat はここでは 救えません。タイムスタンプがプレフィックスの eventKey が単調なので、新しい書き込みは すべて1つの狭いソートキー範囲の先端に落ち、切り分けるものがないからです。より新しい KeyRangeThroughputExceeded のスロットリング理由が、まさにこれを名指しします。テーブル ではなく、1つのパーティションのキー範囲が上限を超えているのです。

修正はキャパシティのスライダーではなく、データモデルにあります。ホットキーを 書き込みシャーディングしましょう。小さなサフィックスを付け足して、1つの論理的な アリーナを N 個の物理パーティションに広げます。

arenaId = "ARENA#7f3a#3"   # shard 0..9, chosen per write

読み取りはそのときシャードにまたがって分散し、クライアント側でマージします。アプリケーション コードの1行に触れる前に、各シャードのキーの形と QueryDynamoDB 式ビルダーでプロトタイプできます。

1つのニュアンス:LSI の例外

ストレージがパーティションキーごとに_確かに_上限されるケースが1つあります。がなければ、アイテムコレクションは、格納バイトとスループットの 両方を提供するために必要なだけ多くのパーティションにまたがって分割されます——数十億の ソートキーの値でも問題ありません。

LSI を追加すると、1つのパーティションキーのコレクション全体が単一の 10 GB パーティション に収まらなければなりません。LSI がそれを共有するからです。それが GSI vs LSI で扱う PK ごとの崖であり——ほとんどのチームが GSI に手を伸ばすもう1つの理由です。

パーティションを冷たく保つ設計

あなたが実際に制御できるてこは、パーティションキーです。行数に対して多くの別々の値を 持つものを選び、トラフィックが均等に広がるようにしましょう。(さらなるパターンは シングルテーブル設計に。)

  • 高カーディナリティのキー。 ユーザーごと、テナントごとのキーは、みなが一斉に叩く 日ごと、ステータスごとのキーに勝ります。
  • 既知のホットキーに注意。 「現在のトーナメント」や「今日」の値は、出荷後ではなく前に、 集中のリスクです。
  • 避けられないホットキーをシャーディングする。 1つのキーが並外れたトラフィックを 取らざるを得ないとき、サフィックスが標準の逃げ道です。

キャパシティに余裕があるのにスロットリングするのは、1つのパーティションがホットである という合図です。偏ったアイテムコレクションを調べ、シャーディングしたキーのレイアウトを DynoTableで予行演習しましょう——自分のテーブルに向け、SQL Workbench で パーティションキーを GROUP BY してどのキーが支配的かを見て、ページャーに呼び出される前に 修正をモデル化しましょう。

更新日