DynamoDB Auto Scalingを使うときの注意点

投稿者: | 2017/12/14

Amazon DynamoDB(以下、DynamoDB)のキャパシティ(Read, Write)が、負荷に応じて上下するAuto Scaling機能が今年発表されました。

新機能 – Auto Scaling for Amazon DynamoDBについて | Amazon Web Services ブログ

今までは多めのキャパシティを確保しなければならず、その分は余計なコストになっていたのですが、Auto Scaling機能によってコストの最適化ができるようになりました。
私が担当しているシステムでもAuto Scaling設定したDynamoDBテーブルがいくつかありますが、思わぬ落とし穴があったことに気が付きました。

スケールダウンしてくれない!

負荷がかかり、キャパシティがスケールアップした後、しばらくすればスケールダウンしてくれるだろうと思っていたのですが、いつまで経ってもスケールダウンしないケースがありました。

Minimum provisioned capacityを1、Maximum provisioned capacityを1,000に設定したDynamoDBがあるとします。

以下の図のように、12/4 02:00(UTC+0)に急激にReadが走ったことで、ReadCapacityがスケールアップされました。Readが走ったのは最初だけでその後はまったくリクエストが送信されなくなりました。リクエストが途絶えた(=負荷がかからなくなる)ため、スケールダウンするだろうと思っていたのですが、いつまでたってもスケールダウンしません。結局、スケールダウンしたのは、12/4 10:30(UTC+0)頃とかなり時間が経過した後でした。

dynamodb_autoscaling_1

グラフを拡大していくと、02:00(UTC+0)頃にリクエストが来たのを最後にRead Capacityが拡大されたままになっています。

dynamodb_autoscaling_2

スケールダウンが始まったのは、10:34(UTC+0)にリクエストが来た後の10:55(UTC+0)でした。リクエストとスケールダウンまでにタイムラグがあるのは、CloudWatchアラームの設定によるものです。

dynamodb_autoscaling_3

つまり、スケールアップ後にDynamoDBにリクエストが来ないとスケールダウンせず、同じキャパシティを保ったままになる ということです。

ドキュメントを読む

ちゃんとドキュメントにも書いてました。

重要
現時点では、テーブルの消費されたキャパシティーがゼロになった場合、Auto Scaling はプロビジョニングされたキャパシティーをスケールダウンしません。回避策として、Auto Scaling が最小キャパシティーにスケールダウンするまでテーブルにリクエストを送信するか、ポリシーを変更して、プロビジョニングされた最小キャパシティーと同じになるまでプロビジョニングされた最大キャパシティーを減らすことができます。
注記
AWS マネジメントコンソール を使用してテーブルや グローバルセカンダリインデックス を作成する場合、DynamoDB Auto Scaling はデフォルトで有効になります。Auto Scaling の設定はいつでも変更できます。詳細については、「AWS マネジメントコンソールと DynamoDB Auto Scaling の使用」を参照してください。
http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/AutoScaling.html

解決策

ドキュメントに「Auto Scaling が最小キャパシティーにスケールダウンするまでテーブルにリクエストを送信する」とあるので、定期的にDynamoDBにリクエストする仕組みを構築する必要があります。

Webアプリとかであれば、ユーザ数がある程度存在するサービスであれば、随時DynamoDBにリクエストされることになるため、対応はしなくても良いと思います。

今回のような一日に数回程度しかリクエストしない場合、CloudWatch EventsでLambdaを定期的に実行し、DynamoDBにリクエストする処理を行わせておくのが良いでしょう。

最後に

DynamoDBのAuto Scalingは、Application Auto Scalingと呼ばれ、EC2 Auto Scalingと似て非なるものなので、違いについて理解していく必要がありますね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*