[blackbird-dynamodb] Monitoring AWS DynamoDB


この[プラグイン](https://github.com/Vagrants/blackbird-dynamodb)ではDynamoDBの各種Metricを取得します。

What metric does it get?
------------------------

各TableにおけるMetricsと各APIにおけるResponse timeが取得できます。

### Table Metrics

まずは各TableのMetricsから。下表のStatisticsはどんな計算式で取得するか(Sumで単位時間あたりの合計値、Avgで単位時間あたりの平均のような)を示しています。


| Metric Name                   | Statistics | Detail |
|-------------------------------|------------|--------|
| UserErrors                    | Sum        | Clientのエラー |
| SystemErros                   | Sum        | AWS側のエラー(ほとんどないでしょう、と思いたいですね) |
| ThrottleRequests              | Sum        | Provisioned Capacity Unitsの上限に達してしまってThrottledなRequestの数 |
| ReadThrottleEvents            | Sum        | Provisioned Capacity Unitsの上限に達したRead系リクエスト |
| WriteThrottleEvents           | Sum        | Provisioned Capacity Unitsの上限に達したWrite系リクエスト |
| ProvisionedReadCapacityUnits  | Maximum    | Tableに指定されているProvisionedReadCapacityUnitsの数 |
| ProvisionedWriteCapacityUnits | Maximum    | Tableに指定されているProvisionedWriteCapacityUnitsの数 |
| ConsumedReadCapacityUnits     | Maximum    | 消費したReadCapacityUnitsの数の単位時間あたりの最大値 |
| ConsumedReadCapacityUnits     | Average    | 消費したReadCapacityUnitsの数の単位時間あたりの平均値 |
| ConsumedWriteCapacityUnits    | Maximum    | 消費したWriteCapacityUnitsの数の単位時間あたりの最大値 |
| ConsumedWriteCapacityUnits    | Average    | 消費したWriteCapacityUnitsの数の単位時間あたりの平均値 |

#### about UserErrors

UserErrorsとざっくり言われても感じだと思うんですが、SDK側でDynamoDB呼び出してるところのエラーです。具体的には4XX系のStatusCodeが返ってきたときですね。

* 認証エラー
* パラメータ足りてない(Hash KeyもしくはRange QueryでRange Keyの指定がないとか)
* Provisioned Throghputが足りてない

#### about Each CapacityUnits

DynamoDBは後ろ側で複数のshardを持った分散DBです。しかし設定するCapacityUnitsはTable全体に対して割り当てられます。shardはCapacityUnitsの大きさに比例して分割、スケールアウトしていくので問題ないと思いがちです。実際スケールアウトとか負荷とか気にしなくていいのはすばらしいところだと思います。

しかし、CapacityUnitsはTableに対して割り当てるので、各shardはその値をshardの数で割り算したものになっちゃいます。ConsumedReadCapacityUnitsが全然上限に達してないのに、LimitExceededExceptionが出てるんですが！！！！ってことが起こりうる可能性があるってことです。

これは(まぁドキュメンテーションちゃんと読めば結構しっかり書いてあるんですが、、、)hash keyの分散があまくてvalueがかたよってhot shardができてしまっているせいです。一度起こってしまうと直すのは結構大変だと思うので、、、ここはできれば設計段階でうまくやりたいですね。

### Each Operation Metrics

APIが成功した時のResponseTimeとrange query発行時に返ってきたItemの数が取得できます。たとえばScan APIとか Query APIがあまりにも多くのItemを返しているなら要注意です。(どちらかと言えば先にELBのLatencyとかが悪くなってってそっちで気づきそうですが)

ResponseTimeに関しては以下のものがあり、

* PutItem
* DeleteItem
* UpdateItem
* GetItem
* BatchGetItem
* BatchWriteItem
* Scan
* Query

取得したItem数には

* Scan
* Query

があります。いずれの値もすべてMaximumとAverageを取得するようにしてあります。


How to Install
--------------

すいません！[まだpipとRPMを用意してない](https://github.com/Vagrants/blackbird-dynamodb/issues/1)のでなる早で対応しますね。


Configuration
-------------

オプションとしては以下のものがあります。

| Key Name | Default | Require | Detail |
|----|----|----|----|
| region_name | us-east-1 | No | AWSのリージョン名です |
| aws_access_key_id | - | Yes | AWS Acces Key ID |
| aws_secret_access_key | - | Yes | AWS Secret Access Key |
| table_name | - | Yes | DynamoDBのTable名です |
| hostname | - | Yes | Zabbix上のHostnameです(先に作っておくことをｵﾇﾇﾒ) |
| module | - | Yes | どのpluginを使用するかなので、ここは**dynamodb**で固定です |
| ignore_metrics | - | No | 取得したくないMetricがあればカンマ区切りでかいてくださいまし |
| ignore_operations | - | No | 取得したくないOperationのMetricがあればカンマ区切りでかいてくださいまし |

### about ignore_XXXXX parameter

ignore_metricsは取得したくない値がある場合(CloudWatchも一ヶ月の無料枠を越えてAPI Callするとお金かかっちゃうので)、`ignore_metrics = UserErrors,ConsumedWriteCapacityUnits`みたいな感じでカンマ区切りでかいてくださいまし。

ignore_operationsも同様で、俺はBatchWriteとScan APIは使ってねえからって方は`ignore_operations = BatchWriteItem,Scan`感じで書いていただけると！

### Example

コンフィグファイルのサンプルです

```ini
# セクション名はなんでもおｋなんですが、内部的には生成されるThreadの名前になるので、他とかぶらない方がいいかもですね。Debug LogにはThread Nameでるということもあって、僕はDynamoDBのTable名にしています。
[ANYTHING_OK]

# AWS Information
region_name = ap-northeast-1
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = YYYYYYYYYY

# DynamoDBのTable名を記入くだしあ
table_name = YOUR_DYNAMODB_TABLE_NAME

# Zabbix上のHostnameです。zabbix上の制約もあってなかなかこういうサーバに紐付かないのってどうしようか悩むんですが、Table名と同じHostnameを作成して使ってます。
hostname = HOSTNAME_ON_ZBX_SERVER

# dynamodb固定です。
module = dynamodb
```

こんな感じですかね！