内部
テーブルがスロットルするのに CloudWatch の平均使用率は 50% 未満で、アダプティブキャパシティは修正策のように聞こえるが、1 つのパーティションキーが依然として不釣り合いなトラフィックを吸収する。
物理パーティションのメンタルモデルなしでは、それらの振る舞いはランダムに見える。
このセクションは深い側だ。パーティションキーがパーティションへどうハッシュされるか、リクエストルーターがどうデータを見つけるか、GSI がどう別にパーティション化されるか、そして今日の DynamoDB が元の Dynamo 論文からどこまで離れたか。
モデリングとインデックスが腹に落ちたあとに読む。前のセクションが渡したルールを説明する。
このセクションで身につくこと
- ハッシュ分布とアイテムコレクションサイズからホットキー症状を予測できる。
- なぜ GSI がベーステーブルに遅れ、自分の GSI 書き込みを強整合で読めないかを説明できる。
- アダプティブキャパシティを、1 キー上の無制限バーストではなく再配分として説明できる。
- パーティション分割とストレージ配置を、なぜ
Queryが 1 つのアイテムコレクションをソートキー順に読むかに結びつけられる。
読む順番
- パーティションキーの仕組み: ハッシュキーからパーティション割り当てへ。スループット分離の単位。
- 物理パーティション: パーティションごとの上限、分割、そして文脈の中での 10 GB LSI コレクション上限。
- アダプティブキャパシティ: パーティション横断でのキャパシティ借用。持続する偏りでの限界。
- ストレージの内部: パーティションのアイテムをキー順に保つ B-tree と、3 つの AZ にまたがるリーダーベースのレプリケーション。
- リクエストルーティング: ルーターフリート、パーティションマップの参照、リーダー読み取りとレプリカ読み取り、そしてスロットリングが起きる場所。
- GSI の内部: 別パーティション、非同期伝播、インデックスアイテムあたりのストレージオーバーヘッド。
- Dynamo 論文から DynamoDB へ: 歴史的な系譜。2007 年の設計が何をし、何がそれに置き換わったか。
パーティションキー値を共有するすべてのアイテムは、1 つのアイテムコレクションを形成する。それは DynamoDB が複数のパーティションに分割するまで 1 つのパーティションに置かれる(LSI があると分割されない)。
毎秒 10,000 イベントを PK = TENANT#acme へ書くと、テーブルに何千ものパーティションがあっても、書き込みユニットは一握りの物理パーティションに集中する。
アダプティブキャパシティは静かなパーティションから余剰を移せるし、忙しいキーのコレクションはソートキーで分割され得る。それでも 1 つのホットなアイテムや、ソートキー順に書き込まれるキーは、パーティションの上限でスロットルする。解決策は、より高いカーディナリティのキーか、ホットなままにしておくべきキーへの書き込みシャーディングのサフィックスだ。ホットパーティションが両方を扱う。
GSI の伝播は非同期で、AWS によれば通常条件では通常 1 秒未満だ。インデックス上に
ConsistentRead の逃げ道はない。
ワークベンチで練習する
DynoTable をダウンロードし、偏っていると分かっているテーブルで設定 を開いて、キー構造とインデックスを比べる。それから重いテナントのパーティションキーと静かなものに Query を実行し、キーあたりのアイテム数を比べる。
SQL Workbench では、境界づけられた Scan または Query 結果の上でパーティションキーを GROUP BY し、画面上でどのキーが最も多くのアイテムを運ぶかを見る。
その集約は取得済み行に対してクライアント側で走る。テーブルを無料でスキャンはしない。
アイテムサイズ計算機 は、大きなアイテムコレクションがなぜ分割閾値に近づくかを説明するのに役立つ。アイテム数はトラフィックではなくストレージの偏りを示す。DynoTable は CloudWatch メトリクスやパーティションヒートマップを露出しない。
トラフィックについては、テーブルまたは GSI で CloudWatch Contributor Insights を有効にし(最もアクセスされるキーと最もスロットルされるキー)、ReadKeyRangeThroughputThrottleEvents と
WriteKeyRangeThroughputThrottleEvents メトリクスを監視する。
GSI の書き込み増幅と結果整合がすでに馴染みになるよう、インデックスのあとに内部を読む。