Amazon Web Services ブログ
Amazon DynamoDB のプロビジョンドキャパシティを使用した突発的なトラフィック増加への対処
Amazon DynamoDB テーブルでプロビジョンドキャパシティを使用する場合、突然のリクエストトラフィックの増加 (スパイク) に対して、スロットルされることなく対処するための最善の方法を検討するのは課題の一つです。スロットルは、リクエストレートが設定された制限を超えたことを DynamoDB が検知した場合に発生するサービス応答です。たとえば、テーブルの書き込み容量ユニット (WCU) を 10,000 にプロビジョニングしており、トラフィックが 20,000 を消費するレートでアクセスされた場合、やがてスロットルが発生し、スロットルされたリクエストを処理するためリトライをする必要があります。
突発的かつ長時間続くトラフィックスパイクほど、テーブルにスロットルが発生する可能性が高まります。ただし、突発的なトラフィックに対して、スロットルの発生を避けることができないわけではありません。ここでは、トラフィックのスパイクに対処するための 8 つの設計と、それぞれの利点と欠点を紹介します:
- Auto Scaling とバーストキャパシティを利用する
- Auto Scaling のターゲット使用率を調整する
- オンデマンドモードに切り替える
- バックグラウンド処理をセルフスロットルする
- バックグラウンド処理をスロースタートする
- スパイクのタイミングを予測できる場合、Auto Scaling スケジュールを使用する
- スパイクのタイミングを予測できない場合、積極的に Auto Scaling の調整を使用する
- 戦略的に一定レベルのスロットルを許容する
DynamoDB のスロットルに関する背景
DynamoDB において、読み取りおよび書き込みリクエストがスロットルされる状況は主に 2 つあります。第一に、テーブルへのリクエストレートがテーブルのプロビジョンドキャパシティを超えた場合。第二に、特定のパーティションへのリクエストレートがすべてのパーティションに存在するハードリミットを超えた場合。この投稿では、テーブルレベルのスロットルに焦点を当てています。これらは急激なトラフィックスパイクに最も関連する制限です。
テーブルおよびパーティションの制限について詳しく知りたい場合は、「DynamoDB のスケーリング: パーティション、ホットキー、Split for heat がパフォーマンスに与える影響 (第 1 部: ローディング)」を参照してください。
DynamoDB のプロビジョニングされたテーブルでは、プロビジョニングされたスループット容量を割り当てることでテーブルの読み取りおよび書き込みの能力を明示的に制御します。読み取りスループット (読み取りキャパシティユニット、または RCU で表される) および書き込みスループット (書き込みキャパシティユニット、または WCU で表される) を割り当てます。割り当てるほど、スロットルが発生するまでにテーブルまたはインデックスで実行できる読み取りまたは書き込み作業が増え、時間ごとのコストも上がります。
グローバルセカンダリインデックス (GSI) は、ベーステーブルとは異なるプロビジョニングされたスループット容量を持っています。それらの制限はテーブルと同じように機能します。この投稿の残りの部分では、「テーブル」という用語はテーブルとインデックスの両方を指すことがあります。
1. Auto Scaling とバーストキャパシティを利用する
通常、トラフィックは一日中変動します。プロビジョンドキャパシティテーブルでこれを処理するクラシックな方法は、Auto Scaling 機能をオンにすることです。Auto Scaling はテーブル上の消費されたキャパシティを監視し、その応答としてプロビジョンドキャパシティの増減を調整します。最小値 (これ以下にはならないように) 、最大値 (これ以上にはならないように) 、およびターゲット使用率 (プロビジョニングされた合計量に対して、消費されている量をこの割合に保つように試みる) を構成します。Auto Scaling は通常のエンドユーザートラフィックの変動や一時的なスパイクに対処するために調整されます。
Auto Scaling はターゲット使用率を超える 2 分間の消費キャパシティを観測すると、プロビジョンドキャパシティを上方に調整します。利用率がターゲット使用率ラインよりも 20 % (相対ではなく、2,000 ベーシスポイントとして) 低い状態を 15 分間観測すると、プロビジョンドキャパシティを下方に調整します。スケールアップはいつでも発生できますが、スケールダウンはより厳格なルールがあります。これは「Amazon DynamoDB のサービス、アカウント、およびテーブルのクォータ」で説明されています。
「1 日あたりの DynamoDB テーブルで実行できるプロビジョンドキャパシティーの減少数には、デフォルトのクォータがあります。日付は、協定世界時 (UTC) に従って定義されます。特定の日に、その日に他の減少をまだ実行していない限り、1 時間以内に最大 4 回の減少を実行することから始めることができます。その後、前の 1 時間に減少がない限り、1 時間あたり 1 回追加で減少を実行できます。これにより、1 日で減らすことができる最大の回数は 27 回になります (1 日の中で最初の 1 時間は 4 回、その後は 1 時間ごとに 1 回)。」
「テーブルとグローバルセカンダリインデックスの減少制限は別々に設定されているため、特定のテーブルのグローバルセカンダリインデックスにはいずれも、独自の減少制限が設定されています。」
Auto Scaling は Amazon CloudWatch を使用して消費キャパシティを観測します。CloudWatch メトリクスは即座ではなく、2 分以上の遅延があります。これは Auto Scaling が DynamoDB テーブルを監視する際に、常に少し過去を見ていることを意味します。Auto Scaling はプロビジョニングされた量を変更するために必要なデータが揃うまでに最短 4 分かかります。
Auto Scaling のターゲット使用率は、この時間ウィンドウ内でのトラフィックスパイクに対応するための余裕を提供します。テーブルが 70,000 WCU を消費している場合、70 %のターゲット使用率を持つ Auto Scaling は 100,000 WCU をプロビジョニングします。追加の 30,000 WCU は、Auto Scaling がより高い量をプロビジョニングできるようになるまでのトラフィックスパイクを処理する余裕 (パディング) です。これにより、最も極端なトラフィックスパイクを除いて、スロットルが発生することはありません。
パディングを超えるスパイクが発生する場合、DynamoDB はバーストキャパシティを提供し、テーブルが一時的にプロビジョニングされたレベルを超えることを許可します。詳細は「DynamoDB のスケーリング: パーティション、ホットキー、Split for heat がパフォーマンスに与える影響 (第 2 部: クエリの実行)」を参照してください。バーストキャパシティは常に有効です。
図 1 は典型的な Auto Scaling の動作を示しています。ゆらぎのあるオレンジの線は一日中にわたる 300,000 WCU から 650,000 WCU までの書き込みトラフィックの消費を示しています。水平の青い線は Auto Scaling によって制御されるプロビジョニングされた書き込み容量です。必要に応じて上下に動きます。
図 1 : Auto Scaling の動作 – ゆらぎのあるオレンジの線は書き込みの消費を示し、水平の青い線はプロビジョンドキャパシティです
真夜中直後 (グラフの 3/4 の位置) を注意深く見ると、スロットリングの影響が見られます。オレンジの消費線は 375,000 WCU から 640,000 WCU に急激にジャンプし、520,000 WCU に設定された青いプロビジョンドキャパシティラインをはるかに超えました。この一時的な超過は、バーストキャパシティによって許可されました。スパイクが続き、数分後にはバーストキャパシティが使い果たされたため、オレンジ色の消費ラインがプロビジョニングされたラインまで下がり、Auto Scaling によってプロビジョニングされた青色のラインが上方に引き上げられ、消費が回復するまでの約 1 分かかりました。 (黒い矢印はこの出来事を指しています) 。
図 2 は、4,000 WCU から 18,000 WCU にユーザーロードを急激に増加させ、スロットルを生成するように設計された、1 時間のシンセティックテストを示しています。このシンセティックテストには、本当のユーザー負荷のようなランダムなジッタが含まれていますが、すべて人工的に生成されたものです。そのため、さまざまな動作を微調整して結果をテストすることができます。
この最初のテストのテーブルは、70 % のターゲット使用率で Auto Scaling が有効になっています。上側の図には、結果として得られた消費キャパシティ (変動している青い線) とプロビジョンドキャパシティ (四角い赤い線) が表示されています。下側の図には、同じ時間枠内のテーブルのスロットル数が表示されています。スパイクは急で、スロットルを引き起こすのに十分な長さがあります。
注:赤い線は、Auto Scaling イベントログで説明されているとおり、分単位のスケーリング活動を正確に示すために手書きされています。CloudWatch はプロビジョンドキャパシティの情報を分単位では受け取りません。
図 2 : シンセティックテスト – テーブルが 70 %のターゲット使用率で構成され、トラフィックが 4,000 WCU から18,000 WCU に急増する状況を示しています
このテストは、最初に 4,000WCU から 5,000 WCU を消費する比較的平らなトラフィックから始まります。Auto Scaling により、プロビジョンドキャパシティは約 7,500 WCU に維持されます。トラフィックの単純な変動はパディングによって処理されます。そして、13:07 に書き込みトラフィックが急激に 18,000 WCU にジャンプします。最初はスロットリングは発生しません。バーストキャパシティが余剰の使用を許可します。しかし、13:11 にはバーストキャパシティが尽き、書き込みレートはプロビジョニングされた量に下がり、他のすべてのリクエストはスロットリングされます。スロットリングは 13:13 まで続き、その後、Auto Scaling によってプロビジョンドキャパシティは 26,000 WCU まで増加します。これは、スパイクに対処するのに十分な量であり、別のスパイクがあった場合に備えたパディングも行われます。最終的に、スパイクが収束してから約 15 分後に、Auto Scaling はプロビジョニングされた量を元に戻します。
この投稿の残りの部分では、デフォルトの Auto Scaling では処理できない、非常に急激で持続的な読み取りまたは書き込みトラフィックの増加のシナリオを含むアクセスパターンを持つテーブルがある場合の設計について検討します。
2. Auto Scaling のターゲット使用率を調整する
考慮すべき調整の一つは、Auto Scaling のターゲット使用率を低く設定することです。これは、予測できない時間にエンドユーザーのトラフィックが予想外に発生し、スロットルを回避して低いレイテンシを維持したい場合に効果的です。
Auto Scaling のターゲット使用率は、テーブルがスパイクを処理するために手元に保持するパディングの量を制御します。これは 20 %から 90 %までの範囲で設定できます。低い値はより多くのパディングを意味します。例えば、ターゲットが 40 %の場合、現在のトラフィックレベルの 1.5 倍をパディングに割り当てます。つまり、10,000 WCU をアクティブに消費しているテーブルは、40 %のターゲットを達成するために 25,000 WCU をプロビジョニングします。低いターゲット使用率には 3 つの利点があります。
- スパイクを処理するためにより多くのパディングが提供される。
- スパイクがプロビジョニングされたレベルを超える場合、バーストキャパシティの許容が増加する。なぜなら、バーストキャパシティの許容はプロビジョニングされた量に比例しているためです。
- Auto Scaling をより迅速に立ち上げることができます。Auto Scaling は、消費されたキャパシティがどれだけターゲット使用率を超えて増加したかを見て、どれだけ増やすかを決定します。スロットルの数は考慮しません。より多くのパディングがあると、予期せぬスパイクのうちの大部分が検知され、それを使用して大きなジャンプを計算できます。パディングがほとんどない場合、スパイクはより抑制されて見え (容量を消費する代わりにスロットルが発生するため) 、Auto Scaling はより小さなステップで進みます。
デメリットはコストの増加です。プロビジョニングされた量に基づいて料金が発生するため、より多くのパディングはより多くのコストを意味します。また、Auto Scaling がトラフィックのスパイクに応じてプロビジョンドキャパシティを上方に調整するたびに、再び下方に調整するまでに一定時間がかかる可能性があります。その期間中には追加のコストがかかります。スロットルとコストのバランスを見て、適切なターゲット使用率を選択します。
Auto Scaling のターゲット使用率を調整する場合は、ベーステーブルだけでなく、GSI (グローバルセカンダリインデックス) も考慮することを忘れないでください。
図 3 は、以前と同じトラフィックパターンを再現していますが、今回はターゲット使用率を 60 %に設定しています。スロットリングは発生しません。
図 3 : シンセティックテスト – テーブルが 60 %のターゲット使用率で構成され、トラフィックが 4,000 WCU から 18,000 WCU に急増する状況を示しています。今回はスロットルが発生していません。
低いターゲット使用率はより多くのパディングを提供しました。テストの最初の 10 分間では、Auto Scaling は前回のテストとは異なり、7,500 WCU ではなく 9,000 WCU に近くプロビジョニングしました。18,000 WCU への急激なジャンプは 14:28 に発生し、14:35 には Auto Scaling がプロビジョニングされた量を上方に調整しました。図 2 と同じくらいの大きなスパイクが発生しても、低いターゲット使用率のテーブルでは一切スロットルが発生しませんでした。
ここで低いターゲット使用率が提供した 2 つの利点は次の通りです。まず第一に、余分なパディングがあったため、スパイク中に必要なバーストキャパシティが少なかったことです。第二に、スパイク前に高いプロビジョニング量を確保しておくことで、消費できるバーストキャパシティがより多くなっていました。この組み合わせにより、このシナリオでは一切スロットルが発生しませんでした。
3. オンデマンドモードに切り替える
スロットルの回避が最優先の場合に考慮すべき有用なデザインの一つは、テーブルをオンデマンドモードに変更することです。
オンデマンドでは、価格は完全に消費量に基づいています。各リクエストにはわずかな料金が発生します。秒ごとに一定量の RCU および WCU を割り当てて時間単位で支払うのではなく、リクエストごとに読み取りリクエストユニット (RRU) または書き込みリクエストユニット (WRU) を消費します。オンデマンドではプロビジョニングはなく、自動スケールアップやスケールダウンも必要ありません。急増するワークロードや予測不可能なワークロードに最適です。
オンデマンドテーブルは、突然のトラフィックスパイクに対するスロットリングの発生確率を大幅に減少させます。オンデマンドテーブルは、2 つの理由でのみスロットリングします。まず第一に、パーティションの制限を超えた場合 (プロビジョニングモードと同じ) 。第二に、テーブルへのトラフィックがアカウントのテーブルレベルの読み取りまたは書き込みスループット制限を超える場合です。これらはデフォルトで 40,000 のガードレールに設定されていますが、これをより高く設定することは可能で、より高く設定しても追加料金は発生しません。
図 4 は、同じトラフィックパターンを再現していますが、今回はオンデマンドモードのテーブルです。プロビジョニングされた値はありません (赤い線はありません) し、テーブルレベルのスロットルもありません。
図 4 : オンデマンドモードはトラフィックの急激な増加に対して即座に反応するため、スロットリングが発生しません
テーブルをオンディマンドに設定して、そのまま使うことができます。プロビジョニング、ターゲット使用率、スケールアップまたはスケールダウンについて考える必要はありません。テーブルはプロビジョニングモードとオンデマンドモードの間で自由に切り替えることができます。テーブルは 24 時間ごとにオンデマンドモードに切り替えることができます。また、テーブルはいつでもプロビジョニングモードに戻すことができます。テーブルをオンデマンドモードに変更して、1 日のうちスパイクが予想される時間に使用し、他の滑らかなトラフィック時間帯に対してはプロビジョニングモードに変更すると便利かもしれません。
オンデマンドテーブルはプロビジョニングテーブルよりも高価であるという一般的な誤解があります。時にはそうであり、時にはそうではありません。比較的平坦なトラフィックの場合、コストの面でプロビジョニングモードが優れています。ワークロードにトラフィックスパイク (急激な上昇と下降) が多いほど、オンデマンドモードの方がコスト優位になります。十分なスパイクがあれば、オンデマンドモードがより低コストの選択肢になる可能性があります。なぜなら、オンデマンドモードはすべてのパディングに関連する追加のコストを回避し、スパイク後のダウンサイジングの待ち時間がないからです。
数学的には、プロビジョニングされたテーブルの達成利用率が 15 %未満の場合、オンデマンドモードはより低コストな選択肢になります。達成された使用率は、消費されたキャパシティの合計を、その月のプロビジョンドキャパシティの合計で割ったものとして計算されます。ダウンサイジングの遅れのため、ターゲット使用率よりも低くなります。
4. バックグラウンド処理をセルフスロットルする
トラフィックの急増が、ある程度制御できるバックグラウンド処理によって引き起こされている場合は、バックグラウンド処理をセルフスロットルさせるという別のオプションを検討する必要があります。基本的には、バックグラウンド処理の消費レートを制限させることで、エンドユーザーのトラフィックと過度に競合しないようにし、必要な Auto Scaling の増加を抑制します。
大幅なスパイクは、背後で何らかのバックグラウンドアクティビティが行われることが原因となることがよくあります。新しいデータセットのロード、日次アイテムのリフレッシュ、履歴データの選択的な削除、または分析のためにテーブルをスキャンするなどの状況では、バックグラウンド処理がどのように振る舞うかを制御できるかもしれません。
バックグラウンド処理がセルフスロットルのレートで実行されるようにします。通常の Auto Scaling のパディングに簡単に収まるようなレートを選択します。このようにすると、開始時にはスロットリングを引き起こさず (ホットパーティションがないと仮定) 、Auto Scaling はテーブルに必要なパディングを復元するために上方に調整できます。もし外部のパーティーがスパイキートラフィックを駆動させている場合は、アプリケーションアクセスポイントで各外部パーティをレートリミットできるかどうかを検討してください。
バルク処理は、各リクエストで ReturnConsumedCapacity
を要求し、1 秒あたりどれだけの容量を消費しているかを追跡することで、セルフスロットルできます。消費量が高すぎる場合は、処理を遅くすることができます。複数の別々のクライアントプロセスを使用している場合、クライアントごとに一定の最大容量消費率を許可することができます。
次の図は、セルフスロットルのバルク処理がスパイクのサイズを制限し、スロットリングを回避する様子を示しています。テーブルは再び図 2 と同じく 70 %のターゲット使用率を持っていますが、今回はバルク処理タスクが少し遅く、少し長く実行されるようになっているため、リクエスト率はわずか 14,000 WCU にしか上昇していません。
図 5 : 18,000 WCU ではなく 14,000 WCU にジャンプすることで、スロットリングが回避されます
14,000 WCU への小さなスパイクは、スパイク中に消費されるバーストキャパシティが少なくなり、テーブルがスロットリングする前に Auto Scaling が上向きに調整するための時間を与えます。
このセルフスロットルのアプローチは、バックグラウンド処理が穏やかなペースで実行されることが許容される場合に機能します。その場合、これには Auto Scaling が上方に調整する量を制限するという追加の利点があります。バックグラウンド処理が 10 分間で一定の 4,000 WCU または 5 分間で 8,000 WCU を消費する場合を想像してみてください。オンデマンドテーブルではこれら 2 つのオプションは同じ価格です。ただし、Auto Scaling を使用するプロビジョニングテーブルでは、より穏やかなジョブはより小さな Auto Scaling の増加を引き起こします。Auto Scaling の減少を 1 時間待たなければならない場合、それははるかに低いプロビジョニングキャパシティでの 1 時間です。ここでのテスト結果では、ピークのプロビジョニングが 20,000 WCU であることがわかります。これは元のテストの 26,000 WCU からの減少です。
このアプローチはスパイクをプラトーに変え、Auto Scaling を使用したプラトーは通常より低いコストになります。
5. バックグラウンド処理をスロースタートさせる
できるだけ早く完了させたいバックグラウンド処理があり、エンドユーザーのトラフィックに影響を与えるスロットルの発生リスクを避けたい場合は、バックグラウンド処理をスロースタートさせることができます。
スロースタートは、前述のようにワークがセルフスロットルすることを必要としますが、最初は緩やかに始め、数分ごとにリクエスト率を増加させます。この緩やかな開始の挙動により、Auto Scaling は需要の増加に対応するための時間を確保できます。スポーツと同様に、何かを壊さないように最初にウォームアップすることが望ましいのです。
この前のオプションと比較して、これは潜在的なコスト削減を提供しませんが、テーブルレベルのスロットリングとエンドユーザートラフィックとの競合のリスクを制限し、 (ウォームアップ後には) 任意に高速なリクエスト率 (構成された Auto Scalingの最大値およびアカウントレベルおよびテーブルレベルの制限のみによる制限) を可能にします。
以下の図は、スロースタートが Auto Scaling のパディング内に収まり、スロットリングを回避するだけでなく、容量を増やす必要性について Auto Scaling にシグナルを送ることができた様子を示しています。
図 6 : バックグラウンド処理のスロースタートにより、Auto Scaling が適応する時間が確保されます
22:49 から 23:00 の間に、トラフィックは 4,000 から 9,000、次に 14,000、最後に 18,000 へと段階的に増加しました。このスロースタートにより、Auto Scaling はバーストキャパシティが消耗される前に独自の増加を行うための十分な時間がありました。テストは元のテストと同じ 18,000 WCU のレートに達し、同じ 70 %のターゲット使用率ですが、スロースタートを始めることですべてのスロットリングを回避しました。
6. スパイクのタイミングを予測できる場合は、Auto Scaling スケジュールを使用する
スパイクがあり、それが予測可能な場合 (たとえば、毎日午前 5 時に大量のロードを実行するか、毎朝午前 9 時にエンドユーザーリクエストが存在しない状態から急激に増加する場合など) 、スケジュールされたスケーリングを使用できます。
スケジュールされたスケーリングでは、テーブルの最小値と最大値を日時に応じて異なる値に設定できます。スケジュールされたアクションを制御するために crontab の表現力を最大限に活用できます。
たとえば、スパイクが来ることがわかっており、それがどのくらいの量かも知っている場合、スパイクを処理できるように Auto Scaling の最小値を大きくすることで、テーブルのプロビジョンドキャパシティを増やすことができます。スパイクが始まると最小値を下げることができます。最小値を下げることはプロビジョンドキャパシティを下げるわけではありません。実際の消費が減少するのを確認した時に、Auto Scaling がそれを下げるだけです。
次の図はトラフィックのスパイクがそのレートにジャンプする 2 分前に、Auto Scaling の最小値を 18,000 WCU に調整するというスケジュールされたアクションを示しています。
図 7 : 予測可能なスパイクの前に積極的にスケールアップした場合
この積極的な Auto Scaling の最小値の調整により、いかなるスロットリングも回避されました。18,000 への最初の上昇はスケジュールされたアクションでした。33,000 への 2 回目の上昇は、実際のトラフィックに対応し、必要なパディングを追加するための Auto Scaling の反応でした。
7. スパイクのタイミングを予測できない場合は、積極的に Auto Scaling の調整を要求する
正確なスパイクのタイミングを予測することはできないが、それが始まりそうなタイミングを検知することができる場合は、積極的に Auto Scaling の調整をリクエストすることができます。
たとえば、朝に大量のバルク処理があることを知っているが、具体的な時刻はわからないという場合を考えます。この場合、バルク処理が始まるときに、特定のキャパシティの引き上げをプロアクティブに要求することができます。あるキャパシティ量を要求するために「準備しろ、今行くぞ」というコールをして、遅延を発生させずにテーブルを調整するイメージです。
実際には、テーブルのプロビジョンドキャパシティを上方に調整するのは非常に速いです。通常、1 分未満で行われます。唯一の注意点は、テーブルのプロビジョニングされた制限を、以前に設定された制限よりも高く上げる場合です。このように新しいハイウォーターマークを設定すると、テーブルはその容量を大きくする必要があり、この増強には時間がかかることがあります。この増強が迅速に達成できるようにするためのベストプラクティスは、テーブルとインデックスを一度、最大の読み取りおよび書き込みレベルでプロビジョニングし、その後再びダウンスケーリングする前に、本番で必要な最大のレベルに設定することです。これにより、後のキャパシティ引き上げを迅速に行うことができます。これをテーブル作成時に行うことができる場合は、それが最速の方法となります。
では、Auto Scaling テーブルのプロビジョンドキャパシティを積極的に増やす方法について説明します。テーブルを直接更新すると、Auto Scaling は変更を認知せず、独自の Auto Scaling アクションで変更を元に戻す可能性があります。より信頼性の高い手法は、Auto Scaling の最小値を新しいプロビジョンドキャパシティとして設定することです。これにより、Auto Scaling はプロビジョンドキャパシティを増やし、また、その発生を認識します。
キャパシティの各リクエスタはコーディネーターにアクセスし、テーブルまたは GSI に一定量の追加キャパシティを要求し、それが届くのを待ってから、遅延なく、かつテーブルレベルのスロットリングを引き起こすことなく開始するべきです。
コーディネーターは各リクエストを受け取り、現在のトラフィックを調査し、要求されたキャパシティを追加し、新しい Auto Scaling の最小値を割り当てます。数分後、バルクワーカーのアクティビティがバルク処理の終了までプロビジョニングレベルを高い要求値に保つことを信頼して、最小値を元の値に戻すことができます。ダウンスケールのタイミングを注意深く計る必要はありません。テーブルを素早くアップスケールするだけです。
最終的な結果は、図 7 と同じように見え、同じように振る舞いますが、事前にタイミングを知る必要がないという違いがあります。
8. 戦略的に一定のスロットリングを許可する
最後に考慮すべきデザインは、アプリケーションデザインでスロットリングを戦略的に許可することです。確実に低いレイテンシであることが厳密な要件でない場合はこれを検討してみてください。一部のスロットリングを受け入れることは、コスト効果が高い選択肢となり得ます。
スロットリングは致命的ではありません。また、データベースに損傷を与えることはありません。単にレイテンシを増加させるだけです。
例えば、エンドユーザートラフィックがないテーブルに対してバルク処理を実行している場合、バルク処理がテーブルの最大容量と同じかそれ以上で実行されることで、途中でいくつかのスロットリングが発生するのがちょうどいいかもしれません。スロットルをなくすために容量を上げた場合よりも負荷は少し長くかかりますが、コストは一定になり、すべてのキャパシティが使用されるため、パディングやその他の考慮は必要ありません。
ただし、テーブルにエンドユーザートラフィックが同時に存在する場合、このようなバルク処理を実行すると、エンドユーザーが彼らの書き込みでスロットリングに遭う可能性があり、これはエンドユーザーに認知されるレイテンシを増加させ、問題になるかもしれません。戦略的にスロットリングを許可する選択肢は、クライアントが低レイテンシを必要としない場合に最も適しています。
デフォルトでは、SDK による呼び出しはスロットリングの応答を検知した場合、リクエストを再試行します。これは SDK 自身が行うため、クライアントはスロットリングが発生していることに気付かないことがよくあります。リクエストは数回再試行され、成功すると、クライアントにとっては成功した (通常よりも高いレイテンシのある) リクエストのように見えます。SDK が実行可能なリトライカウントを超えるまで失敗した場合にのみ、プロビジョニングされたスループットが超過した例外が発生します。この例外が表示された場合は、例外をキャッチして (まだ作業が必要な場合は) リクエストを再試行する必要があります。最終的には、リクエストは成功します。テーブルが 10,000 RCU でプロビジョニングされている場合、ミリ秒ごとにリクエスト処理に利用可能な RCU は 10 増加します。
スロットリングイベントは CloudWatch に ReadThrottleEvents
、WriteThrottleEvents
、ThrottledRequests
として表示されます。スロットルされたクライアントの数が少ない場合、クライアントが成功する前に一連の迅速な自動再試行を実行すると、大量のスロットリングイベントが生成される可能性があります。このため、正確なカウントよりもスロットリングイベントの大まかで相対的な大小に焦点を当てるべきです。また、スロットリングはテーブルレベルで発生する可能性がありますが、ホットパーティションがある場合はパーティションレベルでも発生する可能性があります。CloudWatch メトリクスはこの 2 つを区別しませんが、CloudWatch Contributor Insights はこのデバッグに役立ちます。
まとめ
Auto Scaling とバーストキャパシティは、大規模なトラフィックの急激で持続的な増加に対処できますが、急激で持続的な増加ほど、テーブルでスロットリングが発生する可能性が高くなります。
Auto Scaling のターゲット使用率を下げることで、トラフィックの増加に対する余裕を増やすことも、テーブルをオンデマンドモードに切り替えて、設定して忘れるという選択をすることもできます。
サージがバックグラウンド処理によって引き起こされる場合 (大規模で持続的なサージの場合がよくあります) 、バックグラウンド処理をセルフスロットルして消費量を低く抑えるか、または Auto Scaling が適応するのに十分な時間をかけて徐々に開始するようにすることができます。
サージのタイミングを事前に知っている場合は、Auto Scaling の変更をスケジュールして、スループットの最小値をサージを処理するのに十分な値に上げることができます。事前にサージのタイミングがわからない場合でも、開始の瞬間を特定できる場合は、Auto Scaling の増加を積極的にリクエストすることができます。
最後に、低レイテンシが必要ではない場合は、戦略的に一定のスロットリングを許可することを検討できます。
変更を行う際は、関連する GSI の設定も調整することを忘れないでください。
コメントや質問がある場合は、コメントセクションにコメントを残してください。AWS Database Blog で Jason Hunter によって書かれた DynamoDB の投稿やその他の投稿を見つけることができます。
(本記事は 2023/09/20 に投稿された Handle traffic spikes with Amazon DynamoDB provisioned capacity を翻訳した記事です。翻訳は Solutions Architect の嶋田朱里が担当しました。)
著者について
Jason Hunter は Amazon DynamoDB に特化したカリフォルニア拠点の Principal Solutions Architect です。彼は 2003 年から NoSQL データベースに携わっています。また、Java、オープンソース、およびXML への貢献で知られています。
Puneet Rawal は AWS データベースに特化したシカゴ拠点の Sr Solutions Architect です。彼は 20 年以上の経験を持ち、大規模なデータベースシステムの設計と管理に従事しています。