ブログ

【AWS】DynamoDBはオンデマンドモードでもスロットルする!スロットル対策の罠と調査

この記事をSNSでシェア!

はじめに

Amazon DynamoDBのキャパシティ設定の「オンデマンドモード」は、リクエストに応じてキャパシティを自動調整してくれる機能です。私たちは、システムの利用者が増えてDynamoDB読み書きの負荷が上がり、スロットルが増えてきた、といった問題に直面し、対策としてキャパシティ設定を見直している中でプロビジョンドモードからオンデマンドモードへ移行することを検討していました。同じようにキャパシティの調整で移行を検討している方もいらっしゃるのではないでしょうか。

しかし、私たちは実際にキャパシティモードをオンデマンドに移行を実施したあとも解消されないスロットル発生に遭遇しました。オンデマンドモードへの理解に誤りがあったことが判明し、正しいスロットルの原因を突き止めることができました。

本記事では、私たちのチームが経験した失敗談をもとに、オンデマンドモードでも発生するスロットルの正体について共有します。

▼この記事は以下の方を対象としています

  • DynamoDBのスロットル対策でオンデマンドモードへの移行を検討している方
  • オンデマンドモードを利用しているのにスロットルが発生して困っている方
  • 特定のデータにアクセスが集中する「ホットパーティション」を知りたい方

▼本記事で取り扱わないこと

  • 「ホットパーティション」の対策
  • Amazon DynamoDBの基本的な概念やCRUD操作の解説
  • AWS CDKやTerraformによるリソース作成の具体的なコード

1. 背景:頻発するスロットルとオンデマンド化の検討

私たちのプロジェクトでは、コネクティッドデバイスである車両から送られてくる時系列ログを収集・集約し、DBに保存するシステムを運用しています。

このデータ蓄積を担うDynamoDBテーブルにおいて、書き込みスロットルが頻発していました。以下はテーブルへの書き込みのスロットル件数のグラフです。緩やかに右肩上がりの増加がみられます。

課題の整理

  • 現状: デバイスからの大きいデータの書き込み要求により、一時的にプロビジョンド容量を超過。
  • 影響: アプリケーション側でエラーは出ないものの、書き込みを担うAWS Lambdaの処理時間が延び、ユーザー体験の遅延に繋がっていた。

この課題に対して対策を検討する中で、オンデマンドモードであればキャパシティをリクエストに合わせて自動で調整する設定について見直しを実施しました。システム開発当初は上下限を設定したオートスケーリングを有効にした上でプロビジョンドモードを採用していました。当初オンデマンドモードは費用面と想定のデータ量を試算してコストメリットがないと判断しました。

今回改めて調査したところ、2024年の価格改定により、現在のワークロードではオンデマンドモードの方が安価に運用できる損益分岐点にあることが判明しました。損益分岐点の算出は以下のように試算しています。

※前提:2025年調査当時のフランクフルトリージョンのコスト単価、書き込みレートは最大700、読み込みレートは最大100と仮定する

損益分岐として月あたりWriteは約524,160,000リクエスト、Readは約74,880,000リクエストまではオンデマンドモードのほうがプロビジョンドモードよりも安くなる事が試算できました。この分岐点のリクエスト数は当時の月あたりのリクエスト数の半分以下の値だったため、オンデマンドモードにしたほうがコストメリットがあることがわかりました。

以上のことから、「コストメリット」と「スロットル回避」の両立を目指し、私たちはオンデマンドモードへの移行を決断しました。

2. 課題:オンデマンド移行後に発生した2つの事象

検証環境で十分な負荷試験を行い、スロットルが減少することを確認した上でオンデマンドモードを本番環境に適用しました。しかし、適用から1週間以内に、2つの異なるスロットルが発生しました。

1つ目のスロットルは、想定内のスロットルでした。

移行直後の大量書き込み時に、最初のアラートが発生しました。 オンデマンドモードは、「過去のピーク(30分以上前)の2倍まで」であれば瞬時にスケールしますが、それを超える急激なスパイクには対応が間に合わないことがあります。これはオンデマンドの仕様上初回では必然的に発生しうる事象であり、次回以降は解消されるため静観しました。

2つめのスロットルは我々にとって想定外であり、原因が全く不明でした。

1件目から約10時間後、オンデマンドモードのキャパシティがシステムの平常的なリクエストに耐えられる値になっているはずのタイミングで2件目のアラートを確認しました。CloudWatchでテーブル全体の消費WCUを確認しても、上限には全く達していません。

ここで私たちは原因がわからず、追加調査しました。

3. 罠・調査:2種類のスロットルメトリクス

調査の結果、以下の通りスロットルの正体が明確になりました。

DynamoDBには、以下の2つの書き込みに関する内部メトリクスが存在します。

  • WriteKeyRangeThroughputThrottleEvents
  • WriteMaxOnDemandThroughputThrottleEvents

それぞれの説明配下の図のとおり、スロットルの発生するレイヤーの違いがあります。

テーブル全体のキャパシティを定義するのが1つめのレイヤーです。オンデマンドモードへの設定変更を決断した段階では、WriteMaxOnDemandThroughputThrottleEventsで記録されるテーブル全体のスロットル発生の抑止しか考えていませんでした。よって、オンデマンドモードにすることでスロットル発生を限りなく0にすることができると考えていました。

ところが、実際にはWriteKeyRangeThroughputThrottleEventsに記録される、特定のパーティションへの負荷増大によるスロットルの発生があったことがわかりました。これが2つ目のレイヤーでパーティション単位のキャパシティを表します。

キャパシティのレイヤーについては下記の図のようなイメージです。

DynamoDBには「単一のパーティションが維持できるスループットは 1,000 WCU / 秒」というハードリミットがあります。

たとえオンデマンドモードでテーブル全体のキャパシティが数万WCUまでスケールしていても、特定のデバイスIDや特定のタイムスタンプにデータが集中すると、そのパーティションだけが1,000 WCUを超えてしまい、WriteKeyRangeThroughputThrottleEventsが発生するのです。これは「ホットパーティション」と呼ばれる状態です。

4. ホットパーティション対策案

今回のケースではDynamoDBテーブルの書き込みを行う処理のログから、デバイス車両のデータのバッチ書き込みを短時間に大量に集中させていたことがわかっています。

現在本プロジェクトではホットパーティション自体の対策は検討中の段階です。今回のケースに限らず対応策としては下記のような方法を検討できると考えています。

  • 日時情報などのソートキーと合わせてパーティションキーを分散する
    • まだソートキーを導入していない場合は日時情報などを指定することでパーティションキーを分散することが可能です。
    • 本プロジェクトではすでにソートキーが設定されているため、パーティションキーにランダムサフィックスを付与することで、1つの車両にかかる書き込みを複数パーティションに分散させることができます。
    • ただし、スキーマ定義の変更が必要となることや読み取り時にはレスポンス統合が必要な点に注意が必要です。
  • SQS バッファリングする
    • Lambda から DynamoDB に直接書かず、SQS 経由でバッファリングして書き込みレートを分散します。
    • SQS の Lambda Event Source Mapping で MaximumConcurrency を絞ることでスパイクを平滑化
    • スキーマ変更不要・既存データ影響なし
    • ただし、スロットルは軽減されるかもしれませんが、書き込み完了までのレイテンシが増加し、データ反映が遅延状況は変わらない可能性があります。
  • DynamoDB への書き込みデータ量削減
    • 他にS3バケットなどに完全な生データが保存されている場合などは、DynamoDB にはダウンサンプリングしたデータのみ書き込む方法もあると思います。
    • DynamoDB からの読み取りデータが間引かれ、データをグラフ表示する場合は精度が低下するデメリットがあります。

5.まとめ:運用でハマらないための教訓

今回のトラブルシュートを通じて、以下の2点を再認識しました。

  1. オンデマンドモードは万能ではない: テーブル全体はスケールしても、パーティション単位の1,000 WCU制限(秒間)からは逃げられない。
  2. メトリクスの違いを知る: スロットルが起きたら原因が「全体」なのか「特定キー」なのかをメトリクスで切り分ける。

本調査は運用中のシステムの利用者が増加したことによって、DynamoDBテーブルへの読み書きのスロットルが発生し、ユーザー体験に影響を与えるのではないかという懸念から始まりました。オンデマンドモードとプロビジョニングモードの特性と注意点を調査し、普段のリクエスト数のメトリクスグラフなどからオンデマンドモードのほうが柔軟にリクエストに耐えられると判断しました。またコストメリットについても損益分岐点を算出し、総合的にオンデマンドモードに運用メリットがあったため移行を判断しました。実際にオンデマンドモードにしたことでスロットル数は減ったため、テーブル全体でのスロットル発生の抑止には有効であったと考えています。KYOSOでは、こうした「現場でしか得られないAWSの挙動」を蓄積し、より堅牢なシステム設計に活かしています。

投稿者プロフィール

長谷川歩惟
長谷川歩惟
BS事業部所属。2023年中途入社。Python、AWS、Linuxを中心にシステム開発やインフラ設計に携わっています。ブログを通した発信活動の実績を積んで行きたいです。業務で経験した技術やノウハウをわかりやすく共有できるように頑張ります!
この記事をSNSでシェア!