内容
TransactWriteで1000レコードの登録を行ったところ、
ThrottlingExceptionが発生したため、その対応と、
TransactWrite、BatchWrite使い分けメモ
DynamoDB スロットリング発生原因
以下、一般的な発生原因
- トラフィックが前のピークに比べて 2 倍以上である。
- トラフィックがパーティションごとの最大値を超えている。
- トラフィックがテーブルごとのアカウントクォータを超えています。
- テーブルのグローバルセカンダリインデックスがスロットルされている。
以下、1に関するもう少し詳細な情報
ピークトラフィックとスケーリングプロパティ
オンデマンドモードの DynamoDB テーブルは、
テーブル上の以前のピーク トラフィックの最大 2 倍に即座に対応します。
1 秒あたり 50,000 読み取りが以前のトラフィックのピークである場合、
1 秒あたり最大 100,000 読み取りの持続的なトラフィックに即座に対応します。
30 分以内に前のピークの 2 倍を超えると、スロットルが発生する可能性があります。
以降、2に関して検討、対応事項
トラフィックがパーティションごとの最大値を超えている
https://repost.aws/ja/knowledge-center/on-demand-table-throttling-dynamodb
上記には、
テーブルの各パーティションは、
最大 3,000 の読み取りリクエスト単位または 1,000 の書き込みリクエスト単位、
またはその両方を線形的に組み合わせることができます。
パーティションへのトラフィックがこの制限値を超えると、
パーティションがスロットルされる可能性があります。
とある。可能性があるという表現から絶対にスロットルされるわけではない
リクエスト単位については、
リードリクエストユニットとライトリクエストユニットに以下のように記載されている。
- 1読み取りリクエスト単位 = 4KB未満の読み取りリクエスト
- 1書き込みリクエスト単位 = 1KB未満の書き込みリクエスト
- トランザクションリクエストの場合、リクエスト単位は上記の2倍
今回の現象としては、
10回程度TransactWriteで1000レコードの登録を実行した際に、
1回のみThrottlingExceptionが発生した。
そのため、TransactWriteをBatchWriteに変更し、
消費するリクエスト単位を半分にすることで対応。
CloudWatchでCapacityUnitsをTransactWriteとBatchWriteで実際に2倍消費していることが確認できた。
TransactWriteによるトラフィック超過ではない場合、
パーティションのトラフィックを分散するため、書き込みシャーディングを利用し、
PKにサフィックスを付ける等の対策が必要
TransactWrite
- 複数テーブルに対して一括で操作可能
- 一度のリクエストで最大 100 個の項目の挿入、更新、削除操作可能
- 操作途中でエラーとなった場合、全て操作前の状態に戻る
- リクエストに条件(
Condition
)を指定することができる
エラー発生時に全てロールバックされるため、
複数の操作が同時に完了する必要がある場合、複数項目の整合性が取る必要がある場合に有効
BatchWrite
- 複数テーブルに対して一括で操作可能
- 一度のリクエストで最大 25 個の項目の挿入または削除操作可能
- 更新操作は不可、ただし、既存項目に対する挿入を実行すると上書きとなる(エラーにならない)
- リクエストに条件(
Condition
)を指定することはできない - 操作途中でエラーとなった場合、一部は成功し、一部は失敗した状態となり、
失敗した項目はUnprocessedItems
として返却される
DBに対するリクエスト(通信)回数削減、つまり処理時間の削減が可能なため、
大量な項目の追加/削除に有効