はじめに
ITシステムを開発していく中で、システムのパフォーマンスが問題になるケースは多々あると思います。
PoC、開発、負荷試験、本番運用のいずれのフェイズであってもこのような課題は発生し、そのたびにボトルネックの分析と解決は必要になります。
大体において最初は原因がつかめないため、サーバであればCPU利用率、メモリ利用量、ネットワーク帯域、ディスクI/Oなど、およそ考えられうる個所を一通りチェックする必要があります。
AWSのEC2を利用している場合、単純に「念のためEC2のディスクI/Oも確認しといて」と指示しただけでは、十中八九、「EC2のディスクI/Oの値が取れてないんですが」と返ってきます。
毎回口頭で説明するのも効率が悪いので、「これ読んどいて」で済ませるためにこの記事を書きました。
TL;DR
- 殆どの環境において、EC2のディスクとしてEBSが使われている
- CloudWatchにおいて、EBSはEBSとしてのメトリクスが記録される。EC2のメトリクスには含まれない
- ※重要:「[AWSマイスターシリーズ] Instance Store & Elastic Block Store」1はとても良くまとまっているのでちゃんと読もう
EC2で利用できるディスク
EC2ではローカルディスク領域として以下の2種類のものが利用できます。
- Ephemeral Volume
- EBS(Elastic Block Store)
EC2リリース当初はEphemeral Volumeしか利用できなかったのですが、その後EBSが利用できるようになりました。
そしてEBSがルートボリューム(つまり「/」)として利用できるようになり、現在ではEphemeral Volumeは限られた用途でしか使われなくなりました。
Ephemeral Volume
一部のインスタンスサイズでのみ利用できる領域です。
AWS公式ドキュメントでは、**"Instance Store"(インスタンスストア)**とも呼ばれることもあります。
仮想サーバであるEC2が稼働している物理サーバの、ローカルディスクの一部を間借りするようなイメージです。
EC2インスタンスを停止するとデータは消えます。
詳細は「[AWSマイスターシリーズ] Instance Store & Elastic Block Store」1に詳しいです。
これを利用するためには以下の条件を満たす必要があります。
- InstanceのLaunch時に、Instance Storageが利用できるものを選択する
- "Step 4: Add Storage"の際に、明示的に"Instance Store"を追加する
具体的な画面イメージは下記の通りです。
Step 2: Choose Instance Typeにて、「Instance Storage」に「? x ?? (SSD)」と表示されているものを選択します。
Step 4: Add Storageにて、「Add New Volume」を押してパーティションを追加した後、「Instance Store 0」を選択します。
EBS(Elastic Block Store)
通常、デフォルトで利用される領域です。
詳細は末尾のリンクにある「[AWSマイスターシリーズ] Instance Store & Elastic Block Store」に詳しいです。
本稿では詳細は割愛します。
CloudWatchから確認する
CloudWatchのメトリクス上、Ephemeral VolumeはEC2のメトリクスの一部として記録されますが、EBSはEC2とは別のNamespaceで記録されます。
それぞれ下記から参照することができます。
- Ephemeral Volume:
- EC2->Per-Instance Metrics
- EBS:
- EBS->Per-Volume Metrics
両方のディスク領域に負荷をかけ、どちらのメトリクスに変化が表れるか確認していきます。
検証した環境
Instance Size: m3.medium
OS: Amazon Linux AMI 2017.09
dfとmountの実行結果は下記の通りです。
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.9G 60K 1.9G 1% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/xvda1 7.8G 1021M 6.7G 14% /
/dev/xvdb 3.9G 8.1M 3.7G 1% /media/ephemeral0
$ mount
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=1918920k,nr_inodes=479730,mode=755)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,relatime)
/dev/xvda1 on / type ext4 (rw,noatime,data=ordered)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
/dev/xvdb on /media/ephemeral0 type ext3 (rw,relatime,data=ordered)
事前準備
以下の2つの作業を実施します。
- Bonnie++をインストールする
- メモリ消費スクリプトを作成する
今回は、ディスクに負荷をかけるためにBonnie++を利用します。
操作するディスク容量に対して空きメモリ容量が大きいと、キャッシュが利用されてしまい、ディスクに最大負荷をかけることができません。
通常、物理メモリの2倍の容量のファイルに対して操作を行う必要がありますが、Ephemeral Volumeでは小さすぎます。
# m3.mediumの物理メモリは4GB、Ephemeral Volumeも4GBです。
そこで今回は、強制的にメモリを消費した状態でBonnie++を実行させます。
メモリ消費スクリプトは下記に載せておきました。
上記スクリプトを実行し、メモリを大量に消費している状態にしておきます。
freeコマンド、/proc/meminfo等から確認しておきましょう
$ free
total used free shared buffers cached
Mem: 3855812 3361812 494000 60 9196 98832
-/+ buffers/cache: 3253784 602028
Swap: 0 0 0
Ephemeral VolumeのディスクI/Oを確認
Bonnie++の実行(Ephemeral Volume)
以下のコマンドでEphemeral Volumeに負荷をかけます。
ローカルのSSDはパフォーマンスが良く、すぐに終わってしまうので、10回連続で実行することにします。
# bonnie++ -u root -d /media/ephemeral0 -r 1536
CloudWatchメトリクスの確認(Ephemeral Volume)
以下の操作で、Ephemeral VolumeのディスクI/Oを確認することができます。2
- AWS Management ConesoleからCloudWatchを開く。
- 「Metrics」→「EC2」→「Per-Instance Mertrics」をたどり、対象のInstanceIdでフィルタをかける。
- 以下の4つの項目をにチェックを入れ、グラフを表示させる。なお、*Opsは左軸、*Bytesは右軸に表示させると見やすい。
- DiskReadOps
- DiskWriteOps
- DiskReadBytes
- DiskWriteBytes
EBSのディスクI/Oを確認する
Bonnie++の実行(EBS)
以下のコマンドでEphemeral Volumeに負荷をかけます。
これも10回連続で実行することにします。
今回検証した構成ではそれほどパフォーマンスが良くないので、しばらく時間がかかると思います。
# bonnie++ -u root -d / -r 1536
EBS ID(EBS Volume ID)を確認する
まず、対象のEBSのEBS IDを調べます。
この例では、EC2にアタッチしているEBSは1つであり、またこれがルートデバイスとなっています。
- AWS Management ConesoleからECを開く
- 「Instances」から、対象のEC2インスタンスを選択する
- 「Root device」のリンクをクリックし、ポップアップを表示させる
- EBS ID(vol-?????????????????)が確認できる
CloudWatchメトリクスの確認(EBS)
EBS IDを確認したら、CloudWatchメトリクスから確認できます。3
ここでは取り急ぎ主要な項目のみ確認します。
- AWS Management ConesoleからCloudWatchを開く。
- 「Metrics」→「EBS」→「Per-Volume Mertrics」をたどり、上記で確認したEBS IDでフィルタをかける。
- 以下の4つの項目をにチェックを入れ、グラフを表示させる。なお、*Opsは左軸、*Bytesは右軸に表示させると見やすい。
- VolumeReadOps
- VolumeWriteOps
- VolumeReadBytes
- VolumeWriteBytes
まとめ
Ephemeral VolumeおよびEBSに負荷をかけた時間帯と、CloudWatchメトリクスで確認できるグラフの時間帯が一致していることが確認できたかと思います。
殆どのケースではEC2のローカルディスクとしてEBSを利用していると思います。
CloudWatchメトリクスを確認する際は、間違えないように気をつけましょう。
なお本題とは関係ありませんが、ローカルのSSDはやっぱり速いですね。
バッチ処理等で巨大な一時ファイルの生成が必要な場合は、Ephemeral Volumeが必須かと思います。