[新機能] Amazon DynamoDBでAuto Scalingが可能に!

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

大栗です。

本日DynamoDBがAuto Scalingに対応したというアップデートがありました!

Auto Scaling

今回対応したDynamoDBのAuto Scalingは負荷に応じてwrite capacity units(書き込み容量ユニット)とread capacity units(読み込み容量ユニット)のスループットを上下できるものとなります。DynamoDBのスループットを自動的に制御できるDynamic DynamoDBと似ている機能となります。

CloudWatchでDynamoDBの以下のメトリクスを元に状態を監視してスループットを上下させます。

  • ConsumedReadCapacityUnits
  • ConsumedWriteCapacityUnits
  • ProvisionedReadCapacityUnits
  • ProvisionedWriteCapacityUnits

CloudWatchのアラームは以下の様な物が作成されます。

No. 名前 しきい値
1 TargetTracking-table/usertable-AlarmHigh-12345678-1234-1234-1234-123456789012 5 分間 に対する ConsumedWriteCapacityUnits (ConsumedWriteCapacityUnits) > 210
2 TargetTracking-table/usertable-AlarmHigh-12345678-1234-1234-1234-123456789012 5 分間 に対する ConsumedReadCapacityUnits (ConsumedReadCapacityUnits) > 210
3 TargetTracking-table/usertable-AlarmLow-12345678-1234-1234-1234-123456789012 15 分間 に対する ConsumedWriteCapacityUnits (ConsumedWriteCapacityUnits) < 150
4 TargetTracking-table/usertable-AlarmLow-12345678-1234-1234-1234-123456789012 15 分間 に対する ConsumedReadCapacityUnits (ConsumedReadCapacityUnits) < 150 5|TargetTracking-table/usertable-ProvisionedCapacityHigh-12345678-1234-1234-1234-123456789012|15 分間 に対する ProvisionedReadCapacityUnits (ProvisionedReadCapacityUnits) > 5
6 TargetTracking-table/usertable-ProvisionedCapacityHigh-12345678-1234-1234-1234-123456789012 15 分間 に対する ProvisionedWriteCapacityUnits (ProvisionedWriteCapacityUnits) > 5
7 TargetTracking-table/usertable-ProvisionedCapacityLow-12345678-1234-1234-1234-123456789012 15 分間 に対する ProvisionedReadCapacityUnits (ProvisionedReadCapacityUnits) < 5
8 TargetTracking-table/usertable-ProvisionedCapacityLow-12345678-1234-1234-1234-123456789012 15 分間 に対する ProvisionedWriteCapacityUnits (ProvisionedWriteCapacityUnits) < 5

今回のAuto Scaling対応に伴って、1日にReadCapacityUnitsとWriteCapacityUnitsを減少できる操作回数が4回から9回に増加しているようです。自動で変更するので操作できるか回数が増えて助かりました。

Auto Scalingを試してみる

DynamoDBのAuto Scalingを試してみます。YCSBを使用して負荷を掛けてスループットがどのように変化するのかを確認してみます。

DynamoDBの設定を行う

DynamoDBのテーブルを作成します。YCSBのデフォルト設定に合わせるために、以下を入力して、テーブル設定でデフォルト設定の使用のチェックを外します。

  • テーブル名:usertable
  • プライマリキー:firstname(文字列)

DynamoDB_·_AWS_Console

テーブル設定でデフォルト設定の使用のチェックを外すと、「セカンダリインデックス」、「プロビジョニングされたキャパシティ」、「Auto Scaling」が表示されます。

「Auto Scaling」の項目で読み込みキャパシティー書き込みキャパシティーのチェックを入れて内容を設定します。個々ではデフォルトの設定である以下の設定を行っています。

読み込みキャパシティー 書き込みキャパシティー
ターゲット使用率 70 % 70 %
プロビジョニングされた最小キャパシティー 5 ユニット 5 ユニット
プロビジョニングされた最大キャパシティー 10000 ユニット 10000 ユニット
同じ設定をグローバルセカンダリインデックスに適用 チェックあり チェックあり

DynamoDB_·_AWS_Console

一番下でAuto Scalingを実行するためのIAM Roleを指定します。Roleを作成していない時には「新しいロール」を選択します。設定するポリシーは以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:UpdateTable",
                "cloudwatch:PutMetricAlarm",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:SetAlarmState",
                "cloudwatch:DeleteAlarms"
            ],
            "Resource": "*"
        }
    ]
}

Auto Scalingの設定を行ったら「作成」をクリックしてテーブルを作成します。

YCSBをセットアップする

NoSQLのベンチマークツールであるYCSBを使用して負荷をかけます。YCSBを導入する環境はAmazon Linux 2017.03を想定しています。

READMEの通りにYCSBをダウンロードして、展開、移動します。

$ curl -O --location https://github.com/brianfrankcooper/YCSB/releases/download/0.12.0/ycsb-0.12.0.tar.gz
$ tar xfvz ycsb-0.12.0.tar.gz
$ cd ycsb-0.12.0

移動先のYCSBの展開先でファイルを作成します。

AWSCredentials.propertiesはAWSのアクセスキーを設定します。残念ながらIAM Roleに対応していないようなので諦めてアクセスキーを発行して入力します。

AWSCredentials.properties

accessKey = AKIAIOSFODNN7EXAMPLE
secretKey = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

dynamodb.awsCredentialsFileはDynamoDBのアクセス先の情報を設定します。

dynamodb.properties

dynamodb.awsCredentialsFile = AWSCredentials.properties
dynamodb.primaryKey = firstname
dynamodb.endpoint = http://dynamodb.ap-northeast-1.amazonaws.com

workloads/first_attackは負荷の掛け方を設定します。

workloads/first_attack

workload=com.yahoo.ycsb.workloads.CoreWorkload
recordcount=1000
operationcount=3000000
insertstart=0
fieldcount=10
fieldlength=100
readallfields=true
writeallfields=false
fieldlengthdistribution=constant
readproportion=0.95
updateproportion=0.05
insertproportion=0
readmodifywriteproportion=0
scanproportion=0
maxscanlength=100
scanlengthdistribution=uniform
insertorder=hashed
requestdistribution=zipfian
hotspotdatafraction=0.2
hotspotopnfraction=0.8
table=usertable
measurementtype=histogram
histogram.buckets=100
timeseries.granularity=100

負荷をかける

ここからは負荷を掛けていきます。

まずは初期データを作成します。

bin/ycsb load dynamodb -P workloads/first_attack -P dynamodb.properties

初期データを作成したので、負荷を掛けます。

bin/ycsb run dynamodb -P workloads/first_attack -P dynamodb.properties

負荷を掛けている時の状況をCloudWatchのメトリクスで確認してみます。

消費した容量ユニット(≒アクセスした件数)のグラフです。

CloudWatch_Management_Console

こちらはAuto Scalingで設定されたスループットのグラフです。負荷に応じてスループットは向上しています。

CloudWatch_Management_Console

こちらはスロットルが発生した件数のグラフです。最初はスロットルが大量に発生していましたが、スループットの向上により発生しなくなりました。

CloudWatch_Management_Console

YCSBを停止して負荷を無くしてしばらく経つとスループットが低下します。

CloudWatch_Management_Console

まとめ

Management Consoleで設定を行うとCloudWatchのアラームが自動で設定されて簡単にAuto Scalingの設定を行うことができました。しかしCloudWatchのConsumedReadCapacityUnitsやConsumedWriteCapacityUnitsなどを元にスループットを変化させるためスパイクには対応できません。EC2やECSのAuto Scalingと同様にスパイクが想定される場合には事前にスループットを増加したりAmazon DynamoDB Accelerator(DAX)を構成しておくべきです。

しかし、事前にコストを掛けずに負荷に対応できるため、ほとんどのテーブルに設定するのが良いかと思います。