よくハマるEC2のIO周りの性能の考え方まとめ

こんにちは
某SIerで働いており、主にクラウドの導入について支援させて頂いているたくまです。

日本のAWS Ambassadorによる[Japan APN Ambassador Advent Calendar 2022](https://qiita.com/advent-calendar/2022/japan-aws-ambassador)の13日目の記事となります。

AWS Ambassadorについては、[APN Ambassadorsってなんだ？2021年度版](https://qiita.com/keizoa/items/8c2c68783c49e609f78a)を見て頂ければと思います。



企業様でAWSを使うきっかけの一つとして、よくあるのがハードウェア保守切れではないでしょうか？
その際に

- 移行後に思ったほど、性能が出ない。もしくは遅くなる。
- しっかりサイジングしたハズなのに夜間処理が長くなる。
- 突然処理が遅くなった。
などなど、性能にまつわるトラブルに遭遇する事もあるのではないでしょうか？

色々性能周り相談をうけたり、実案件を見ている中で個人的に移行後の性能問題TOP3は、この3つが多いかなと思います。

- IO周りのサイジングの考慮漏れ
- DBのバージョン差異によるクエリの実行計画のブレ
- AZ間のレイテンシー


今回の記事では、IO周りのサイジングについてまとめてみました。

# 1. IOPSとスループットについて

そんなの知っている！という人は、飛ばして、2から読んでもらえたらと思います。

- IOPS : ストレージが1秒あたりに処理できるI/O(書き込み・読み込み)の数
(こちらの性能が求めれられるのは、細かなファイルにいっぱい読み書きするイメージです）

- スループット : 1秒秒間にどれぐらいデータを転送できるか
（こちらの性能が求められるのは大きなファイルをコピーするイメージです）

この2つの性能指標を基に必要な性能を考えます。
経験的にオンプレからの移行の場合は、HDDが太い帯域のインターフェイスで直結されている構成からの移行が多く、その場合、HDDなので、IOPS性能は既存ではそれほど必要とされてないけど、スループットは結構使っていたというケースがよくあります。

この場合、スループットが足りない事が多く「夜間処理が長くなった」という様な性能問題を引き起こす可能性が多いです。


# 2. サイジングについて


## 2.1 サイジングの場合の考慮する指標
移行後のサイジングを考慮する際にCPUとメモリしか見ていないとトラブる事が多いです。
大体オンプレの場合はCPUは、30%も使われていたらいい方で、10%未満で利用率でずっと推移しているシステムもよくあるのではないでしょうか？

ただ、バッチ処理やDBでの処理の多くは、IO性能が必要とされる事が多いのですが、サイジングで考慮されてない事もよくあります。

IO関係のサイジング重要なポイントになるので既存システムがある場合は、既存のIO周りの性能情報を基にサイジングに落としていきます。

Windowsで言えば、パフォーマンスモニタのこの指標を基に必要なAWSのインスタンスとディスクを行います。

- Disk Transfers/sec：IOPS
- Disk Bytes/sec：スループット


## 2.2 AWS関連で考慮するポイント

 AWSの場合、インスタンス側（EC2)とストレージ側（EBS）それぞれに性能指標があるので、それぞれで考慮が必要です。  

![ec2-ebs-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/69f7aa8a-f9f3-51f8-4013-b4f7c9bb8668.png)

上の図でいうところの、青丸がインスタンス側（EC2）の性能指標、赤丸がストレージ（EBS)となります。
それぞれで考慮が必要なのでサイジングの際は両方で必要性能を満たすようにインスタンスタイプとEBSを選定していきます。

当然一番性能指標が低い所がボトルネックになるので、インスタンス側（EC2）がネックになるのかストレージ（EBS)側がネックになるのか以下ドキュメントを確認しながら、サイジングます。
 
### EC2指標　
![bluePoint.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/ac8aec30-9d34-b3c9-075b-8bf08f5e31c8.png)
[Amazon EBS 最適化インスタンスを使用する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-optimized.html)

この表にインスタンスごとの、スペックが書かれているので、必要性能を満たすインスタンスを選定します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/64c873fd-9f68-f8a1-0355-3cfda5d2256c.png)
 ＊印が書いているインスタンスは、性能がバーストするタイプのインスタンスなので、ベースパフォーマンスとバーストした際のパフォーマンス両方見る必要があります。 

毎日30分の夜間処理中だけ、IOが必要とされているケースはバーストするタイプで問題ないですが、30分以上ピーク性能が必要であれば、ベースパフォーマンスを見る必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/7ff23e3c-ce0a-94be-aab7-6e3fcba9b8c7.png)


### EBSの指標

[汎用 SSD ボリューム](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/general-purpose.html)
[Provisioned IOPS SSD ボリューム](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/provisioned-iops.html)

ストレージタイプによって、IOPSとスループットの指標がそれぞれあるのでそれぞれ確認が必要となります。

この指標は、EBSボリューム１つあたりの指標になるので、この図のように複数のEBSボリュームを使っていて、ディスクのストライピングやDBファイルの分散ができていれば足し合わせた性能が確保できます。

![ec2-ebs.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/70fefa37-9b64-d892-e57f-0a15d5dc9144.png)


## 2.3 実機での確認
それぞれインスタンスとEBSを組み合わせて、どのぐらいの性能がでてどこがネックになるのか実機で確認してみました。検証に使ったツールは[CrystalDiskMark](https://crystalmark.info/ja/software/crystaldiskmark/)です。

赤字が性能のボトルネックになっているところです。

### インスタンス側がネックになるパターン

##### 測定環境
- EC2：c4.large　(<font color="Red">4,000IOPS</font>、スループット <font color="Red">62.5MiB/秒</font>)
- EBS：io2 100GB （10,000IOPS　スループット　500MiB/秒）

##### 結果
[Read]
`  SEQ    1MiB (Q=  8, T= 1):    63.755 MB/s [     60.8 IOPS] <129921.47 us>`
`  RND   16KiB (Q= 32, T=16):    65.241 MB/s [   3982.0 IOPS] <126632.29 us>`

[Write]
 ` SEQ    1MiB (Q=  8, T= 1):    64.582 MB/s [     61.6 IOPS] <127820.38 us>`
 ` RND   16KiB (Q= 32, T=16):    65.378 MB/s [   3990.4 IOPS] <126139.01 us>`

高性能なEBSを使っていますが、インスタンス側の性能にひっぱられて、インスタンス側の性能がIOの限界性能になっています。

### ディスク側がネックになるパターン

##### 測定環境
- EC2：c5.9xlarge(40,000IOPS、スループット 1,187.5MiB/秒)
- EBS：io2 100GB(<font color="Red">10,000IOPS</font>　スループット　<font color="Red">500MiB/秒</font>)

##### 結果
[Read]
 ` SEQ    1MiB (Q=  8, T= 1):   531.055 MB/s [    506.5 IOPS] < 15762.21 us>`
 ` RND   16KiB (Q= 32, T=16):   171.201 MB/s [  10449.3 IOPS] < 48733.23 us>`

[Write]
 ` SEQ    1MiB (Q=  8, T= 1):   530.026 MB/s [    505.5 IOPS] < 15767.82 us>`
 ` RND   16KiB (Q= 32, T=16):   167.966 MB/s [  10251.8 IOPS] < 49669.21 us>`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/94e47f3a-5c67-d9f1-1c38-c7dac87c4df4.png)

インスタンスタイプは、IO性能が高いものを選択していますが、今度は、EBS側の性能がネックになっています。

また、io2のスループット性能は、IOPSに比例して伸びていくため、1,000MiB/秒を確保しようとすると
64,000IOPS割り当てないと出ません。


### gp3測定

スループットだけ稼ぎたい場合の例です。
例えば、io2で1,000MiB/秒のスループットを満たしたい場合、64,000IOPSのEBS1本で構成するか2000IOPSのボリューム2本をストライプする必要があります。

gp3の場合、 IOPS あたり 0.25 MiB/秒のパフォーマンスを確保できるので、4000IOPSのプロビジョニングのみで1,000MiB/秒スループットを確保できる事ができます。
費用を計算するとおよそ1/6ぐらいなので、どの辺りの性能が要求されているか、確認し最適な構成にすることが、コスト面にも大きく関わってきます。

##### 測定環境
- EC2：c5.9xlarge(40,000IOPS、スループット 1,187.5MiB/秒) 
- EBS：gp3 100GB(4,000IOPS　スループット　1,000MiB/秒)
##### 結果
[Read]
 ` SEQ    1MiB (Q=  8, T= 1):  1063.032 MB/s [   1013.8 IOPS] <  7881.89 us>`
 ` RND   16KiB (Q= 32, T=16):    68.331 MB/s [   4170.6 IOPS] <121175.47 us>`

[Write]
 ` SEQ    1MiB (Q=  8, T= 1):  1062.295 MB/s [   1013.1 IOPS] <  7874.71 us>`
 ` RND   16KiB (Q= 32, T=16):    67.319 MB/s [   4108.8 IOPS] <122983.92 us>`

gp3の場合IOPS×0.25としてスループットが確保されるので1,000MiB/秒
必要な場合も4000IOPSで性能が確保できます。


# 3. 既存のIO性能が分からない場合のIOPSの目安

## SAPシステムの考え方を活用
新規システムや既存の情報が取れない場合どれぐらいのIOPSが必要になりそうか、私がおおよその目安としている計算方法について記載します。

バッチ処理等で必要になるスループットに関しては特性に大きく依存するので、一概に言えないですが、オンラインシステムの場合のDBサーバのIOPSは、以下を目安にサイジングしています。

SAP Basis時代が長く、SAPで稼働させるシステムやスペックについて厳密な指標があり、認定されているHWやインスタンスタイプでないと稼働がサポートされません。

この事もあり、稼働できるHWやインスタンスタイプは、一律のSAP固有のSAPS値という指標でベンチマークされ公開されています。この考え方や指標が参考になり、活用しています。

AWSの場合以下表にSAPS値が掲載されています。

[SAP 向け Amazon EC2 インスタンスタイプ](https://aws.amazon.com/jp/sap/instance-types/)
例えば、
c5.largeの場合　2,650SAPS
m5.largeの場合　2,817SAPS
となっているので、インスタンス間の性能差がどれぐらいあるのか参考にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/0305af7a-18da-7732-f6c8-1dbaf886bcec.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918922/f61ad7bf-143a-76b7-f95d-de0dfac9d60f.png)

## 必要なIOPSの目安

SAP on AWSで目安として採用されている計算方法を利用しています。
DBサーバで必要なIOPSは、オンライン処理を実行するAPサーバのSAPS値の合計を基に以下の計算式で算出しています。

　15,0000SAPS 未満：SAPS値×0.4
　15,0000SAPS 以上：SAPS値×0.3

例えば、c5.largeが3台の構成の場合以下のような計算で、3180IOPSを目安としています。
- 2,650SAPS×3台＝7,950SAPS
- 7,950×0.4=3,180IOPS

# 4.最後に

ここまで読んで頂いてありがとうございます。
既に知っている情報もあったかも知れませんが、これを読んで頂いているあなたにとって一つでも参考になる情報があれば幸いです。

もし参考になったらLGTMしてもらえたら励みになります。