EC2 インスタンスを運用していてトラブルがあったとき、EBS の IOPS とスループットを確認したいことがあります。
EBS の IOPS とスループットは AWS マネジメントコンソールの EBS のモニタリングから確認ができます。
EBS のモニタリングは Read と Write がそれぞれ別のグラフになっているため、それらの合計値をひとつのグラフで確認したいときには、以下の画像のように CloudWatch Metrics でグラフを構築する必要があります。
たくさんのインスタンスを管理していると毎回グラフを構築するのが面倒なため、手順を簡略化するためにシェルスクリプトを作成しました。この記事ではグラフの Source を生成するシェルスクリプトと、その使い方を紹介します。
EBS の IOPS とスループットを CloudWatch Metrics でグラフ化する
EBS の IOPS とスループットを CloudWatch でグラフ化するには、提供されている EBS のメトリクスをもとに、自分で計算をする必要があります。計算方法は Amazon EBS のメトリクスに書かれています。以下に重要な部分を抜粋しました。
VolumeReadOps
指定期間内の読み取りオペレーションの総数。その期間の 1 秒あたりの読み込み I/O 操作回数 (読み取り IOPS) の平均を算出するには、その期間の読み取りオペレーション回数の合計をその期間の秒数で割ります。単位: カウント。
VolumeWriteOps
指定期間内の書き込みオペレーションの総数。その期間の 1 秒あたりの書き込み I/O 操作回数 (書き込み IOPS) の平均を算出するには、その期間の書き込みオペレーション回数の合計をその期間の秒数で割ります。単位: カウント。
VolumeReadBytes
指定された期間の読み取りオペレーションに関する情報を提供します。Sum
統計は、期間内に転送されたバイトの総数をレポートします。単位: バイト。
VolumeWriteBytes
指定された期間の書き込みオペレーションに関する情報を提供します。Sum
統計は、期間内に転送されたバイトの総数をレポートします。単位: バイト。
グラフの Source を生成するシェルスクリプト
上記の計算式に従って、CloudWatch Metrics グラフの元となる Source(json) を生成します。
cloudwatch-ebs-iops-source-generator
#!/usr/bin/env bash
#/ Usage: cloudwatch-ebs-iops-source-generator [options] <ec2-instance-id> <index-of-attached-volume>
#/
#/ You can run following commands:
#/ cloudwatch-ebs-iops-source-generator i-012428a14116b9683
#/ cloudwatch-ebs-iops-source-generator i-012428a14116b9683 1
#/
#/ Options:
#/ -h, --help
#/
set -e
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
grep '^#/' < "$0" | cut -c4-
exit 2
fi
EC2_INSTANCE_ID=$1
VOLUME_INDEX=${2:-0}
EBS_VOLUME_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --query "Volumes[$VOLUME_INDEX].VolumeId" --output text --region ap-northeast-1)
cat << EOF
{
"metrics": [
[ { "expression": "m1_0 / PERIOD(m1_0)", "label": "Read IOPS", "period": 60 } ],
[ "AWS/EBS", "VolumeReadOps", "VolumeId", "$EBS_VOLUME_ID", { "label": "$EBS_VOLUME_ID", "id": "m1_0", "visible": false } ],
[ { "expression": "m1_1 / PERIOD(m1_1)", "label": "Write IOPS", "period": 60 } ],
[ "AWS/EBS", "VolumeWriteOps", "VolumeId", "$EBS_VOLUME_ID", { "label": "$EBS_VOLUME_ID", "id": "m1_1", "visible": false } ]
],
"view": "timeSeries",
"stat": "Sum",
"period": 60,
"stacked": false,
"yAxis": {
"left": {
"min": 0
}
},
"title": "Read and Write IOPS"
}
EOF
シェルスクリプトを実行する
上記のスクリプトをファイルに保存し実行権限を与え、以下のように、引数で EC2 インスタンス ID とアタッチされている EBS ボリュームのインデックス(省略可)を指定して実行します。実行するには aws-cli v2 がインストールされ、IAM の設定を済ませておく必要があります。
cloudwatch-ebs-iops-source-generator i-012428a14116b9683 1
CloudWatch の Source が出力されます。
{
"metrics": [
[ { "expression": "m1_0 / PERIOD(m1_0)", "label": "Read IOPS", "period": 60 } ],
[ "AWS/EBS", "VolumeReadOps", "VolumeId", "vol-08d4ab915a88159c6", { "label": "vol-08d4ab915a88159c6", "id": "m1_0", "visible": false } ],
[ { "expression": "m1_1 / PERIOD(m1_1)", "label": "Write IOPS", "period": 60 } ],
[ "AWS/EBS", "VolumeWriteOps", "VolumeId", "vol-08d4ab915a88159c6", { "label": "vol-08d4ab915a88159c6", "id": "m1_1", "visible": false } ]
],
"view": "timeSeries",
"stat": "Sum",
"period": 60,
"stacked": false,
"yAxis": {
"left": {
"min": 0
}
},
"title": "Read and Write IOPS"
}
CloudWatch メトリクスの Source に貼り付ける
- CloudWatch Metrics で Source を選択し
- 出力された json を貼り付け
- Update ボタンを押します。
グラフが表示されます。よく参照するのであれば、このグラフを CloudWatch Dashboard に追加するのも良いと思います。
スループットのグラフを出力するスクリプト
スループットも IOPS と同じように作成します。VolumeReadBytes, VolumeWriteBytes の単位が Byte で、今回は KiB でグラフにしたいので 1024 で割ります。
cloudwatch-ebs-throughput-source-generator
#!/usr/bin/env bash
#/ Usage: cloudwatch-ebs-throughput-source-generator [options] <ec2-instance-id> <index-of-attached-volume>
#/
#/ You can run following commands:
#/ cloudwatch-ebs-throughput-source-generator i-012428a14116b9683
#/ cloudwatch-ebs-throughput-source-generator i-012428a14116b9683 1
#/
#/ Options:
#/ -h, --help
#/
set -e
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
grep '^#/' < "$0" | cut -c4-
exit 2
fi
EC2_INSTANCE_ID=$1
VOLUME_INDEX=${2:-0}
EBS_VOLUME_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --query "Volumes[$VOLUME_INDEX].VolumeId" --output text --region ap-northeast-1)
cat << EOF
{
"metrics": [
[ { "expression": "m1_0 / PERIOD(m1_0) / 1024", "label": "Read throughput (KiB/s)", "period": 60 } ],
[ "AWS/EBS", "VolumeReadBytes", "VolumeId", "$EBS_VOLUME_ID", { "label": "$EBS_VOLUME_ID", "id": "m1_0", "visible": false } ],
[ { "expression": "m1_1 / PERIOD(m1_1) / 1024", "label": "Write throughput (KiB/s)", "period": 60 } ],
[ "AWS/EBS", "VolumeWriteBytes", "VolumeId", "$EBS_VOLUME_ID", { "label": "$EBS_VOLUME_ID", "id": "m1_1", "visible": false } ]
],
"view": "timeSeries",
"stat": "Sum",
"period": 60,
"stacked": false,
"yAxis": {
"left": {
"min": 0
}
},
"title": "Read and Write throughput (KiB/s)"
}
EOF
以下のようにスループットのグラフを出力できます。