LoginSignup
14
6

More than 1 year has passed since last update.

DynamoDBへの大量の読み込みリクエストによるスロットリングエラーの解消

Last updated at Posted at 2022-12-04

はじめに

最近のAPI開発ではLambdaを使って開発する機会が増えていると思います。Lambda開発では一般的にDynamoDBとの相性がよく採用されているケースが多いと思います。

DynamoDBを使うにあたって、テーブル内の1つの要素に対して大量のリクエストがあった場合に、ホットパーティションによるスロットリングの発生してしまう可能性があります。

今回はそのスロットリングの発生から解消までをAWSコンソール上から確認していきたいと思います。

内容

スロットリングとは

一定期間で受けられるリクエストの数を設定して、それを超えてきたら受信拒否してエラーを返却することです。

これはエンドポイントURLに対するリクエスト数が多すぎる場合、制限をかけることでトラフィックの急増に対しバックエンドサービスを守ってくれるそうです。これがDDoS攻撃などに対策になっていると思います。

AWSサービスではこういった制限をかけてくれていますが、作るシステムによっては頻繁にリソースへアクセスが予想されるものもあると思います。その場合は制限を回避するようにしなければいけません。

DynamoDBのスロットリング

プロジョンタイプで予想されるアクセス数に対応できるキャパシティユニットで設定しておけば急なアクセス増加にも対応しておくことはできるが、コストがかかってしまうので、現実的にオンデマンドで対応したいところです。

オンデマンドタイプでは、以下の場合にスロットリングが発生する可能性があるとawsのサイトに記載がありました。

・トラフィックが前のピークに比べて 2 倍以上である。
・トラフィックがパーティションごとの最大値を超えている。
・トラフィックがテーブルごとのアカウントクォータを超えています。
・テーブルのグローバルセカンダリインデックスがスロットルされている。

試したこと

urlをプライマリーキーにしたモックAPIのレスポンスをキャッシュするテーブルを作成し、当該テーブルの1項目に対して1分間あたり500回のgetリクエストを送る。

キー
url PK
response モックAPIのレスポンス

今回のエラー内容

software.amazon.awssdk.services.dynamodb.model.DynamoDbException: Throughput exceeds the current capacity of your table or index. DynamoDB is automatically scaling your table or index so please try again shortly. If exceptions persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html (Service: DynamoDb, Status Code: 400, Request ID: 3PSHGOAO0277BFLPUE899O24PVVV4KQNSO5AEMVJF66Q9ASUAAJG)

CloudWatch Contributor Insights for DynamoDB

こちらのグラフでスロットリングが発生していることが確認できます。

スクリーンショット 2022-12-04 20.25.59.png

回避方法

今回はURLというパーティションキーへのアクセスが集中してホットパーティションとなっていそうだったため、今回の事象は、

・トラフィックがパーティションごとの最大値を超えている。

と仮定して、書き込みシャーディングを使用してワークロードを均等に分散する方法を試してみました。

実際の作業内容は単純で、dynamo保存時にキーに1~100のサフィックスを付与し、同じ内容のものを100項目書き込む方法になります。

以下のような項目になります。

url response
http://test.com?key=value-1 {"response": "test"}
http://test.com?key=value-2 {"response": "test"}
http://test.com?key=value-3 {"response": "test"}
... ...
http://test.com?key=value-100 {"response": "test"}

キャッシュ取得の検索時に、1~100のランダム数をサフィックスに付与することで読み込みが100個分分散されることになりました。

再度実行してみたところエラーはなくなり、正常に終了しておりました。

おわりに

ドキュメント上でDynamoDBの性能の良さは聞いていたが、大量データを扱っても高速に処理してくれることを実際に大量リクエストを送ってみて実感できました。

明日は @Nebel-hb さんの記事です。乞うご期待を!

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6