dynamodb-autoscaling検証

## 概要
先日のアップデートでdynamodbでautoscalingの機能が実装されました。
https://aws.amazon.com/jp/blogs/news/new-auto-scaling-for-amazon-dynamodb/

NoSQLデータベースのベンチマークツールであるycsbを用いてdynamodb-autoscalingの動作を検証できます。
今回は新規に追加された項目「ターゲット使用率」がどのような影響を及ぼすかについて検証します。


## 環境準備
環境準備に伴い、下記を参考にさせていただきました。

http://qiita.com/noralife/items/35a956f682b1aca475f6
http://dev.classmethod.jp/cloud/aws/attack_to_dynamodb_using_ycsb/
http://imai-factory.hatenablog.com/entry/2013/04/05/010858

amazon linux version

```bash
[ec2-user@dynamo-ec2 ycsb-0.12.0]$ cat /etc/system-release
Amazon Linux AMI release 2017.03
```

openjdk-develインストール

```bash
$ sudo yum -y install java-1.7.0-openjdk-devel
```

ycsb導入

```bash
・ダウンロード
$ wget https://github.com/brianfrankcooper/YCSB/releases/download/0.12.0/ycsb-0.12.0.tar.gz

・展開、移動
$ tar xfz ycsb-0.12.0.tar.gz
$ cd ycsb-0.12.0/

・ファイル用のディレクトリ準備
$ mkdir -p dynamodb/conf/

・ベンチマーク対象テーブル(testtable)のプライマリキーを確認しておく
$ aws dynamodb describe-table --table-name testtable | jq -r '.Table.AttributeDefinitions[].AttributeName'
name
```

### YCSB概要

テストデータをdynamodbに読み込ませて

```
./bin/ycsb.sh load dynamodb -P workloads/dyamodb -P dynamodb/conf/dynamodb.properties
```

テストデータを使って負荷をかける。

```bash
./bin/ycsb.sh run dynamodb -P workloads/dyamodb -P dynamodb/conf/dynamodb.properties
```

設定ファイルは下記の3つ

■dynamodb/conf/dynamodb.properties
対象のDynamoDBの情報を設定。変更する部分はプライマリキーくらいかと。
クレデンシャル情報が記載されたファイルもこの中で指定する。

```bash
$ cat dynamodb/conf/dynamodb.properties
dynamodb.awsCredentialsFile = dynamodb/conf/AWSCredentials.properties
dynamodb.primaryKey = name
dynamodb.endpoint = http://dynamodb.ap-northeast-1.amazonaws.com
```

■dynamodb/conf/AWSCredentials.properties
クレデンシャル情報を記載。

```bash
$ cat dynamodb/conf/AWSCredentials.properties
accessKey = XXXXXXXXXXXXXXXXXXXX
secretKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

■workloads/(任意のファイル名)
投入するデータ、実施するベンチマークのステータスを設定。
値はテンプレート`workloads/workload_template`を参考。
※operationcountは1,000,000以上が良いかと。10,000で実行したらスケーリングする前に終わってしまいました……

```bash
$ cat workloads/dyamodb
workload=com.yahoo.ycsb.workloads.CoreWorkload #デフォルト

recordcount=1000 #テーブルにセットするレコード数
operationcount=2000000 #load時のオペレーション数

insertstart=0 #デフォルト
fieldcount=10 #フィールド数、デフォルト
fieldlength=100 #レコードの長さ、デフォルト

readallfields=true #デフォルト
writeallfields=false #デフォルト

table=testtable #テーブル名

fieldlengthdistribution=constant #デフォルト

#load時のオペレーション比率(read80%, update15%, insert5%)
readproportion=0.8
updateproportion=0.15
insertproportion=0.05

#以下テンプレートの値のまま設定
readmodifywriteproportion=0
scanproportion=0
maxscanlength=1000
scanlengthdistribution=uniform
insertorder=hashed
requestdistribution=zipfian
hotspotdatafraction=0.2
hotspotopnfraction=0.8

measurementtype=histogram
histogram.buckets=1000
timeseries.granularity=1000
```

## 検証開始

### 初期のdynamodbキャパシティ設定
1000レコード書き込むので、書き込み容量ユニット(以下WCU)を10確保。
WCU1だとスロットルが発生して時間がかかります……。

![初期設定.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/4f45d920-4353-34e5-6acd-55fe4384183b.png)


### テーブルにテストデータを読み込ませる
1回だけ。10分ほどかかります。

```
$ ./bin/ycsb.sh load dynamodb -P workloads/dyamodb -P dynamodb/conf/dynamodb.properties
```

### auto-scaling設定
いよいよauto-scaling設定です。
RCU/WCUを下げるオペレーションは最大9回/日になっていますが条件があります。
↓の記事を参考にさせていただきました。
http://qiita.com/mokrai/items/6864b8a723a2728565fc
検証する場合は無駄に下げないように初期値を考慮しましょう。

![as1.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/58a643d0-69b4-f41f-089e-2baef5bdf88a.png)

・ターゲット使用率
スケーリングの基準になる値です。以降で検証します。

・IAMロール
[新しいロール]を選択すれば問題ありません。
下記の管理ポリシーが付与されたロールが作成されます。

```json
{
    "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はcloudwatchの値を評価の基準としています。
auto-scaling設定中は動的なcloudwatchメトリクスが作成され、auto-scaling設定解除後に削除されます。



## ターゲット使用率70%の場合

下記設定でcloudwatchの推移を確認します。

|auto-scaling設定|RCU|WCU|
|:---|:---|:---|
|ターゲット使用率(%)|70|70|
|min(ユニット)|10|10|
|max(ユニット)|10000|10000|


### キャパシティの推移
推移は下記の通り

RCU
![70rcu.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/07b141c8-849e-8d6f-d224-740e089d359e.png)


WCU
![70wcu.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/37d75311-06e1-2dbc-708c-3930ff8296f8.png)



## ターゲット使用率20%の場合

下記設定でcloudwatchの推移を確認します。

|auto-scaling設定|RCU|WCU|
|:---|:---|:---|
|ターゲット使用率(%)|20|20|
|min(ユニット)|10|10|
|max(ユニット)|10000|10000|


![20rcu.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/222954e4-1dc4-0978-e785-5e457a6403d5.png)

![20wcu.PNG](https://qiita-image-store.s3.amazonaws.com/0/121456/8e2b1671-f25a-1445-0b3e-c1433d5f530b.png)



###終わりに

負荷のかけ方が一定の場合はキャパシティーの増減が安定したら変化しないので、
そのあたりの調整が必要だと感じました。
cloudwatchメトリクスが動的な値で作成され、それらが基準になってスケーリングされています。
サポートに確認したところ、閾値を超えてのキャパシティ設定もできるとのことですが、その場合は次のタイミングでスケーリングされてしまうとのことです(未検証)。