【速度改善】EC2 インスタンスと EBS ボリュームのボトルネックを調査し対応する実例の紹介

記事タイトルとURLをコピーする

マネージドサービス部 佐竹です。
今回は、トラブルシューティングとして EC2 インスタンスと EBS ボリュームのボトルネックを調査し、そのボトルネック解消のために行った改善対応の記録を一部ご紹介したいと思います。

はじめに 事前知識

EC2 インスタンスと EBS ボリュームは、どちらも「最大スループット」と「最大 IOPS」を設定として持っています。そして、これらが必要な値よりも低い場合に、期待した性能が出ず「ボトルネック」となり得てしまう場合があります。

EC2 インスタンスについて

まず、EC2 インスタンスのインスタンスタイプごとの設定値は以下のドキュメントにまとめて掲載されています。

docs.aws.amazon.com

補足ですが、「最大帯域幅 (Mbps)」の単位が Mbps のため、この値を8で除算すると「最大スループット (MB/秒、128 KiB I/O)」の値と一致します。

ということで、上記ドキュメントの一覧において特に見るべき値は「最大スループット (MB/秒、128 KiB I/O)」と「最大 IOPS (16 KiB I/O)」の2つとなります。

以下はその例です。必要な個所だけ抜き出してみました。

「n」表記なし

インスタンスサイズ 最大スループット
(MB/秒、128 KiB I/O)
最大 IOPS
(16 KiB I/O)
Linux 料金/h
(東京)
r6i.8xlarge 1250 40000 USD 2.432
r6i.12xlarge 1875 60000 USD 3.648
r6i.16xlarge 2500 80000 USD 4.864
m6i.8xlarge 1250 40000 USD 1.984
m6i.12xlarge 1875 60000 USD 2.976
m6i.16xlarge 2500 80000 USD 3.968

「n」表記あり

インスタンスサイズ 最大スループット
(MB/秒、128 KiB I/O)
最大 IOPS
(16 KiB I/O)
Linux 料金/h
(東京)
r6in.8xlarge 2500 87500 USD 3.38832
r6in.12xlarge 3750 131250 USD 5.08248
r6in.16xlarge 5000 175000 USD 6.77664
m6in.8xlarge 2500 87500 USD 2.86416
m6in.12xlarge 3750 131250 USD 4.29624
m6in.16xlarge 5000 175000 USD 5.72832

1時間当たりの利用料は「EC2 オンデマンド料金」で確認できます。

「n」が付与されたインスタンスファミリー

以下のブログでもご紹介しているのですが、「M6in, M6idn, R6in 及び R6idn」と2022年の re:Invent で「n」が付与されたインスタンスファミリーが多数発表されました。

blog.serverworks.co.jp

「n」は「ネットワークと EBS の最適化」を示しており*1、先に紹介した処理性能(最大スループットと最大 IOPS)がそれぞれ強化されたインスタンスファミリーです。

これは先の一覧で抜粋してご紹介した通り、「n」があるインスタンスファミリーは、同サイズの「n」表記がないインスタンスサイズと比較して「最大スループットで倍の性能、最大 IOPS で倍以上の性能」を有します。

本来これらの処理性能を倍にするには、インスタンスサイズを倍にするしかありませんでした。しかしオンデマンド利用料もそれに伴い倍になっています。「n」が付与されたインスタンスファミリーを利用することで、費用を倍まで支払うことなく性能の底上げが可能となります。

EBS ボリュームについて

EBS ボリュームは以下の AWS 公式ドキュメントに記載のある通り複数種類がありますが、HDD を除いた SSD の最新世代のみに絞り込むと基本的には gp3 と io2 の2種類に絞り込めます。

docs.aws.amazon.com

ただし、io2 は特定の条件を満たすことで io2 Block Express(io2bx)となり性能が向上します。よって、この3つを以下に簡単にまとめます。

ボリュームタイプ gp3 io2 io2bx
ボリュームサイズ 1GiB - 16TiB 4 GiB~16 TiB 4 GiB~64 TiB
最大 IOPS (16 KiB I/O) 16,000 64,000 256,000
最大スループット (MB/秒) 1,000 1,000 4,000

gp3

gp3 は gp2 と比較し 20% も安価であり、さらに IOPS と スループットも指定が可能となりました。

IOPS は最低 3,000 から最大 16,000 まで設定が可能で、最低の 3,000 では無料です。スループットは最低 125 から最大 1,000 まで設定が可能で、同様に 125 の設定では無料です。

詳しくは以下のブログも合わせてご覧ください。

blog.serverworks.co.jp

io2 Block Express

io2 Block Express は re:Invent 2020 で発表され、2021年7月頃に一般提供が開始された機能です。

aws.amazon.com

io2 Block Express は以下のインスタンスタイプに対応しており、これらのインスタンスタイプにアタッチされた io2 は io2 Block Express として認識され、設定値の上限が緩和され性能が向上します。

io2 Block Express volumes are supported with C6a, C6in, C7g, C7gd, C7gn, C7i, Inf2, M6a, M6in, M6idn, M7a, M7g, M7gd, M7i, M7i-flex, P5, R5b, R6a, R6in, R6idn, R7a, R7g, R7gd, R7iz, Trn1, Trn1n, X2idn, and X2iedn instances.

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/provisioned-iops.html#io2-block-express

注意点としてスループットが IOPS に比例して拡張されるため、16,000 IOPS 以上で最大スループットである 4,000 MB/秒に到達します。最大スループットが必要な場合は 16,000 IOPS 以上で構築する必要があります。

Modify volume (io2)

実際に試してみると io2 Block Express と認識されている場合、上画像の通り Size (GiB) と IOPS の設定値の上限が向上することがわかります。

加えて、先ほど「n」が付与されたインスタンスファミリーを利用することで、費用を倍まで支払うことなく処理性能の底上げが可能となると記載しましたが、「n」が付与されたインスタンスファミリーの多くが io2 Block Express に対応しているため、r6in や m6in など「n」が付与されたインスタンスファミリーを採用して性能を向上させるメリットはさらに大きいと感じます。

ここまでが事前知識となります。引き続き改善対応の「実例」に進みます。

ボトルネック解消のための対応の実例

状況の確認

ある日、エンドユーザ様より「処理が完了しない」という問い合わせを頂きました。

本処理は AWS で稼働後、定期的に実行してきたとのことですが、特定の条件を伴う「いつもより重い処理」を流し始めたところ想定よりも時間がかかってしまっているとのこと。

そこで調査のためにリソースを確認したところ以下のことがわかりました。

  • インスタンスは「インスタンスA」が対象(※ID は伏せます)
  • インスタンスタイプは r6i.8xlarge
  • インスタンスAにアタッチされている EBS ボリュームは7つ
  • そのうちの1つにデータベースの表領域を持っている「ボリュームB」がボトルネックになっているようだ
  • ボリュームBは gp3 で構築されており IOPS とスループットはそれぞれ 16000 と 1000(※最大)
  • ボリュームBのボリュームサイズは 10,000 GiB で十分であり現状増やす予定はない

表にしてまとめます。

サービス 対象 設定値 最大 IOPS 最大スループット
EC2 インスタンスA r6i.8xlarge 40000 1250
EBS ボリュームB gp3 16000 1000

CloudWatch メトリクスを用いて、ボリュームBの AWS/EBS における VolumeReadBytesVolumeWriteBytes を調査しました。値は最小の「1分」にしてあります。

最大スループット 1000 がボトルネックになっている

これらの値を合算し、さらに単位を合わせて秒間に計算しなおすため「SUM(METRICS())/1000/1000/60」を計算し、描画しています。メトリクスの値が1分間であるため、これを60秒で除算する必要があるためです。

結果として、以前より定期的にボリュームBの最大スループットである「1000」に抵触していたことと(画像にある赤い点線がそれです)、今回の処理が非常に重く時間がかかってしまっていることが判明しました。

処理時間は、開始時刻が「8:49」終了時刻が「18:52」でした。およそ10時間の処理時間です。

IOPS も同様の傾向

ボリュームBの VolumeReadOpsVolumeWriteOps についても同様に確認してみます。これらの値を合算し、秒間に計算しなおすため「SUM(METRICS())/60」を計算し描画しています。

IOPS についてもスループットと同様に、画像の赤い点線の 16000 付近で最大値に抵触することが多く、ボトルネックとなっている可能性が高いことがわかりました。

これらの対応をインフラ(AWS)側から行うことが求められます。

対策の実行と結果確認 その1

まずはボリュームBの最大スループットを拡張するため、io2 にストレージタイプを変更することとしました。

ただし、通常の io2 では最大スループットが gp3 と同様に 1000 MB/s です。このため変更先は io2 Block Express となる必要がありました。io2 Block Express を利用するためには、対応したインスタンスタイプに合わせて変更する必要があります。

そこで、インスタンスタイプも合わせて r6in.8xlarge へと変更することになりました。この変更によりインスタンス側の最大スループットも 1250 から 2500 へと向上が見込めます。

なお同時に IOPS 値もボトルネックとなっている可能性が高いため、IOPS 値も倍の 32000 に拡張することとなりました。

以下が変更後の一覧表です。

サービス 対象 設定値 最大 IOPS 最大スループット
EC2 インスタンスA (r6i.8xlarge→)r6in.8xlarge (40000→)87500 (1000→)2500
EBS ボリュームB (gp3→)io2 Block Express (16000→)32000 (1000→)4000

この状態で再度処理を実行し、どのように改善されたのか確認を行いました。

スループット 4000 に届かず 2500 で頭打ち

同様に CloudWatch メトリクスを用いて、ボリュームBの AWS/EBS における VolumeReadBytesVolumeWriteBytes を調査したところ、確かにスループットが改善されたことがわかりました。

しかし、スループットが期待された「4000」まで行かず画像の赤い点線の「2500」で止まってしまっています。

これは EC2 インスタンス(r6in.8xlarge)の最大スループット 2500 に抵触しているためで、ボトルネックが EBS ボリュームから EC2 インスタンスに移ったことを示しています。

EC2 インスタンスの CloudWatch メトリクスを合わせて確認します。

インスタンスがボトルネックになった状態

インスタンスAの AWS/EC2 における EBSReadBytesEBSWriteBytes を調査しました。値は最小の「1分」にした後 EC2 の場合は Maximum で描画します。これらの値を合算し、さらに単位を合わせて秒間に計算しなおすため「SUM(METRICS())/1000/1000/60」を計算し、描画しています。

ここでも明らかなように、画像の赤い点線の「2500」に抵触して頭打ちとなっており、インスタンス側の最大スループットが頭打ちの原因になっていることがわかります。

この状況での処理時間は、開始時刻が「7:04」終了時刻が「13:56」でした。およそ7時間の処理時間です。

改善後の目標は 12:00 までの完了であるため、さらなる対応が必要となりました。

対策の実行と結果確認 その2

インスタンスタイプ r6in.8xlarge では最大スループットが不足していることが判明したため、対応策としてはインスタンスタイプの変更が必要です。

r6in ファミリーのまま次のインスタンスサイズとなると、ターゲットとなるインスタンスタイプは r6in.12xlarge となります。

しかし以下の表の通り r6in.12xlarge を選択すると利用料金が1.5倍となってしまうことでコストへの影響が大きいことがわかります。

インスタンスサイズ 最大スループット
(MB/秒、128 KiB I/O)
最大 IOPS
(16 KiB I/O)
Linux 料金/h
(東京)
r6i.8xlarge 1250 40000 USD 2.432
r6in.8xlarge 2500 87500 USD 3.38832
r6in.12xlarge 3750 131250 USD 5.08248
m6in.12xlarge 3750 131250 USD 4.29624

そこで、今回はコスト最適化の観点から m6in.12xlarge を選択することとなりました。もともと r6i ファミリーを利用していたのはメモリを確保するためでしたが m6in.12xlarge でもメモリ量は十分と判断できたためです。

この変更によりインスタンス側の最大スループットは 2500 から 3750 へと向上が見込めます。

以下が今回の変更点のまとめです。

サービス 対象 設定値 最大 IOPS 最大スループット
EC2 インスタンスA (r6in.8xlarge→)m6in.12xlarge (87500→)131250 (2500→)3750
EBS ボリュームB io2 Block Express 32000 4000

この状態で再度処理を実行し、どのように改善されたのか確認を行いました。

EBS ボリュームのボトルネック解消

メトリクスは EBS ボリュームのものですが、画像の赤い点線は EC2 インスタンス側の最大スループットである「3750」です。

EBS ボリュームのメトリクスを確認するに、スループットが 3750 に抵触したのは瞬間的なものとなっていたことがわかりました。

EC2 インスタンスのボトルネック解消

画像の赤い点線は同様に EC2 インスタンス側の最大スループットである「3750」です。

こちらもスループットが 3750 に抵触したのは瞬間的なものとなっていたことがわかりましたので、ボトルネックが解消したように見受けられました。

処理時間は、開始時刻が「6:48」終了時刻が「9:53」でした。およそ3時間まで処理時間が短縮されており、目標であった 12:00 までの完了となりました。

これで一旦は対策が完了となりました。

ただし、IOPS については少々気がかりです。

現在もなお IOPS は最大値 32000 に抵触することが多い

画像の通り、IOPS の値は今もなお io2 Block Express の最大 IOPS である 32000 を瞬間的に上回るタイミングが存在しています。

AWS Compute Optimizer

さらに AWS Compute Optimizer でボリュームBの推奨を確認すると、Option 2として IOPS を 39300 まで拡張することが推奨されていました。

このためスループットにおいては十分に改善されましたが、IOPS においてはもう少々改善の余地が残されている状況です。

ただしこれ以上の改善対応は一旦不要と判断して様子見としました。目標となる12:00までの処理完了を達成しているため、これ以上速度を向上させる必要がないというのがその理由です。

まとめ

本ブログでは、実案件で発生したトラブルシューティングとして EC2 インスタンスと EBS ボリュームのボトルネックを調査し、そのボトルネック解消のために行った改善対応の記録をご紹介しました。

今回行った2段階での対応を表にまとめると以下の通りです。

サービス 設定値 IOPS スループット コメント
EC2 r6i.8xlarge 40000 1250
EBS gp3 16000 1000 IOPS と スループットがボトルネック
対応1 ↓ EC2/EBS 共に変更
EC2 r6in.8xlarge 87500 2500 スループットがボトルネック
EBS io2 Block Express 32000 4000
対応2 ↓ EC2 のみ変更
EC2 m6in.12xlarge 131250 3750
EBS io2 Block Express 32000 4000 IOPS がボトルネックの可能性あり

CloudWatch メトリクスの AWS/EC2 における EBSReadBytesEBSWriteBytes の値もまとめて振り返ってみます。

スループットの移り変わり

このように振り返ってみると「ボトルネックは移動する」ということがよくわかる事例になったなという印象です。

また今回行った対応策では「コスト最適化」を鑑み、段階的にスペックを向上させることとなりました。

これは「一度にまとめてスペックをあげ過ぎると、全て解消されるものの原因が不明となりやすい」という状況になる可能性が高いことを鑑みての対応でした。

そして何より「原因が不明なため高コストのままスペックが下げられなくなる」という問題を引き起こしてしまう可能性があります。

こうなってしまうとコストの観点でかなり不利になります。AWS は油断するとすぐに利用料が跳ね上がってしまいますので、特にコストへの影響が高い変更は慎重に行いたいものです。

本ブログが何らかの調査やトラブルシューティング時の参考になれば幸いです。

では、またお会いしましょう。

佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ

マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023 Japan AWS Top Engineers/2020-2023 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。