Linux
AWS
EC2
CloudWatch
aws-cli

AWSでEC2のLoad AverageをCloudWatch metricsに追加するScript

はじめに

AWSでEC2インスタンスを起動すると、自動的にCPUやNetwork I/O, Disk I/OなどのMetricsがCloudWatchに追加される。
しかし、実運用ではこれだけでは微妙に"かゆいところに手が届かない"ことが多い。
例えば、メモリやSWAPの使用率はパフォーマンス改善を検討する上でボトルネックを探る重要な情報な情報だし、Disk使用率を監視して枯渇を防ぐことは障害を未然に防ぐことにつながる。
これらの項目は、Amazonが提供している以下のScriptを導入することで、CloudWatchで監視することができる。

Amazon CloudWatch Monitoring Scripts for Linux
https://aws.amazon.com/jp/code/amazon-cloudwatch-monitoring-scripts-for-linux/

同様に、よく用いられる総合的な負荷の指標として、Load Averageがある。
Load Averageの概要については、Wikipediaを参照。

ワークロード
https://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%89

しかし、EC2インスタンスのLoad AverageをCloudWatchで収集する方法は、AWSのデフォルトでは用意されていないし、上記の"Amazon CloudWatch Monitoring Scripts"でも対応していない。

そのため、Load Averageを取得してCloudWatchに登録するScriptを書いてみた。

必要なもの

  • awscli.noarch
  • bc.x86_64
  • IAM: CloudWatchFullAccess権限

Source

以下のScriptを任意の名前で作成し、Cronで定期実行して使用する。

CloudWatch-LoadAverage.sh
#!/bin/bash
export LANG=C
LOADAVERAGE=`uptime`
LOADAVERAGE=`echo ${LOADAVERAGE##*average: } | awk '{print $1}' | sed -e "s/\,//g"`
CORE=`grep "processor" /proc/cpuinfo | wc -l`
LA_UTIL=`echo "scale=2;$LOADAVERAGE * 100 / $CORE" | bc | sed -e "s/^\./0./"`
aws cloudwatch put-metric-data --namespace "System/Linux" --value $LA_UTIL --metric-name 'Load Average' --dimensions "InstanceId=`cat /var/tmp/aws-mon/instance-id`" --unit "Percent"

(2018/6/14 不具合が発生する場合があったので少し修正)

Load Averageは、そのマシンが使用できるCPU Core数によって性能限界時の最大値が違う。
例えば、1 Coreのマシンであれば1.00が性能限界だし、96個のvCPUを積んでいるm5.24xlargeであれば96.00が性能限界ということになる。
なので、このScriptではLoad AverageをCPU Core数で割った%にすることで、負荷状況を直感的に理解したり、異なるインスタンスタイプ間でも容易に比較できるようにした。
また、他のMetricsとの比較を容易にするため、上記の Amazon CloudWatch Monitoring Scriptsと併せて使用することを想定している。

これまでのMetricsと併せて分析・使用することで、例えばAuto ScalingのTrigger pointを設定したり、負荷テストなどで最適なインスタンスの選定をしたり、Scalabilityの設計をする上で役立つのではないだろうか?