【AWS】ユースケース別にみるEBSのパフォーマンスチューニング
この記事は AWS Advent Calendar 2023 21 日目の記事です。
概要
以前オンプレからLiftをするような案件に関わっていた際に、
EBSのパフォーマンスが思うように出ず苦労したので、
改めてfioで色々なパターンを試しながら、
チューニングポイントを確認してみました。
パフォーマンスの指標
EBSのパフォーマンスをチューニングする際に、
見るべきメトリクスとして以下3点がよく挙げられるのを見かけますが、
EBSでレイテンシは設定できないので、
スループットとIOPSを中心にチューニングしていけばよさそうな気がします。
- レイテンシ
- スループット
- IOPS
事前準備
環境の用意
EC2(t3.small)を1台作成しました。
ディスクは汎用(gp3)を利用し、性能の初期値を以下のように設定して確認してみます。
設定項目 | 値 |
---|---|
IOPS | 3000 |
スループット | 125Mbps |
アクセスパターンの用意
よくあるアプリケーションのアクセスパターンを参考に、
以下2パターンを中心にfioツールを使って検証をしてみました。
- データベース(トランザクション処理 中)
- データベース(ログファイル)
引用:https://sp.ts.fujitsu.com/dmsp/Publications/public/wp-basics-of-disk-io-performance-ww-ja.pdf
ランダムアクセスかシーケンシャルアクセスか不明な時
IOPSやスループットの値を決める際に、
アクセスパターンは非常に大事だと言われています。
AWSのドキュメントでも小さいデータをランダムにアクセスする場合IOPS値が、
ある程度大きいデータをシーケンシャルにアクセスする場合はスループット値が大きく影響すると記載があります。
アプリケーションの開発者、またはソースコードを読み解きアクセスパターンやデータサイズを解析できればよいのですが、なかなか困難な道のりだと思います。
実はソースコードがわからなくてもシステムコールからある程度傾向を把握することが可能です。
具体的にはblktraceコマンドでディスクに対するコールを記録し、
blkparseコマンドで分析をします。
例えば以下はddコマンドで8kbをランダムにディスクに書き込んでいます。
262217600、262218600とランダムに書き込んでいることがわかります。
8,0 0 1 0.000000000 334 Q R 262217600 + 8 [dd]
8,0 0 1 0.000000000 334 Q R 262218600 + 8 [dd]
また、以下はddコマンドで8kbをシーケンシャルにディスクに書き込んだ場合です。
262217600、262217608と連続して書き込んでいることがわかります。
8,0 0 1 0.000000000 334 Q R 262217600 + 8 [dd]
8,0 0 2 0.000005421 334 G R 262217608 + 8 [dd]
上記のようにしてblkparseで結果からプロセスIDでgrepし、対象のアプリケーションがどのようにディスクにアクセスしているのか傾向をある程度つかむことができるます。
ユースケース別のチューニングポイント
1. スループットが頭打ちになるパターン
- fioの設定値
設定項目 | 値 |
---|---|
アクセスパターン | シーケンシャル 100% |
ブロックサイズ | 64kb |
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 125Mbps |
IOPS | 3000 |
データベース(ログファイル)を想定したアクセスパターンを試してみましたが、
結果としてはスループットが設定した上限の125Mbsで頭打ちとなりました。
ブロックサイズが大きいので、
ブロックにアクセスして転送の準備はできているが、
スループットがボトルネックとなり詰まっているようなので、
スループットを上げてみます。
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 125→250Mbps |
IOPS | 3000 |
スループットを上げるとさらに上限まで使うようになりました。
このままスループットをあげていけばよさそうですが、
そもそもSSDではなくHDDのほうが適切かどうか検討する必要がありそうです。
2. EBS間の帯域が頭打ちとなるパターン
- fioの設定値
設定項目 | 値 |
---|---|
アクセスパターン | シーケンシャル write:100% |
ブロックサイズ | 64kb |
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 250→500Mbps |
IOPS | 3000 |
- EC2のインスタンスタイプ
t3.small
パターン1でスループットをさらに上げるとどうなるのか確認をしてみます。
今度はスループット250Mbpsで頭打ちになってしまい、
せっかくスループット値が有効に使われていなさそうです。
EC2とEBS間の帯域は通常ネットワークと共有となっており、
他の通信により帯域が狭まっているのか、
t3シリーズの上限の可能性があるのでEBS最適化があるインスタンスタイプに変更してみます。
- EC2のインスタンスタイプ
t3.small→m5.large
m5.largeは最大スループットが593Mbpsあるのでスループットが有効に使われることに期待し、
再度実行してみます。
今度はスループットが上がりましたが、IOPSが4930となり足を引っ張っているのかもしれません。
試しにIOPSをあげて実施したところ、この後スループットがさらに上がりました。
3.IOPSが頭打ちになるパターン
- fioの設定値
設定項目 | 値 |
---|---|
アクセスパターン | ランダムアクセス read:67% write:33% |
ブロックサイズ8kb |
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 125Mbps |
IOPS | 3000 |
今度はデータベース(トランザクション中程度)のアクセスパターンを想定して試してみました。
スループットが125Mbsを大きく下回っており、
IOPSがreadとwrite合わせてIOPSが3001になり頭打ちになっているようです。
転送する準備ができていないので、
転送するデータサイズも小さく、IOPSが大きくすることで解消できるかもしれません。
IOPSを倍の6000にするとどうなるのか確認してみました。
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 125Mbps |
IOPS | 3000→6000 |
スループットは場合にあがりましたが、IOPSがまだ頭打ちになっているようです。
おそらくIOPSをさらに上げることでスループット値も上がっていくのでしょう。
この後IOPSをさらに倍にしたところ、スループットも上がっていきました。
4.ネットワーク帯域が頭打ちになるパターン
- EBSの設定値
設定項目 | 値 |
---|---|
スループット | 125Mbps |
IOPS | 3000 |
自宅とAWS間でサイト間VPNを用意し、約10GBのファイル転送を実際に試してみました。
自宅とAWS間のサイト間VPN環境について興味がある方はこちらをご参照ください。
VPNの帯域をiperf3で実測したところ約18Mbpsのに対して、
ディスク転送が約16.9Mbpsだったためほぼほぼディスク転送で帯域が使われていました。
CloudWatchのメトリクス(VolumeWriteBytes)でスループットを算出すると16.9Mbpsなので、
ネットワーク帯域が上限でいっぱいか、
IOPSがもしかしたら頭打ちになっているのであげるともう少し性能が上がるかもしれません。
まとめ
- 頭打ちになっているのがスループットなのかIOPSなのか確認し、設定上限なのか確認してみる。
- ネットワーク帯域が上限なのか確認してみる。
- そもそもボリュームタイプが適切なのか検討してみる。
- EBS最適化インスタンスを検討してみる。
基本的なところではあるのですが、改めて実際に手を動かして確認してみると理解が深まりました。
もちろん上記以外にもチューニングポイントはあるとは思います。
ユースケースごとに異なるかと思いますので、iotopやblktrace、iperfやcloudwatchなどを活用しつつ確認ポイントを丁寧につぶして、ボトルネックを洗い出すのがよさそうかなと思いました。
この記事がどなたかの参考になれれば幸いです。
Discussion