はじめに
DBなどのパフォーマンス改善のためEBSをチューニングしよう!となりメトリクスを見たとき、
以下の右半分のようにアイドル時間(VolumeIdleTime
)が既にゼロになっているときがあります。
ここで
「ディスクが完全にBusy状態だからIOPSやスループットを上げるしか無い!!」
と思うのは時期尚早です。
実は、この状態でもEBSのIOPSやスループットに余裕がある場合はよくあります。
それがなぜ発生するのか、どうすればディスクのパフォーマンスを改善できるのかを説明します。
VolumeIdleTimeについて
自分は勘違いをしていたのですが、"VolumeIdleTimeがゼロ = Disk性能上限に達している" というわけではありません。
VolumeIdleTimeがゼロというのは、あくまで ずーーっと読み書きが続いているというだけ で、
極端な話、1ミリ秒に1回のReadでもそうなります。
EBSのパフォーマンスを改善するなら、
VolumeIdleTimeに心奪われず、IOPSとスループットを見る必要があります。
CloudWatchメトリクスでIOPSとスループットを確認する
IOPSとスループットは、CloudWatchメトリクスでカスタムグラフを作ってしまうのがおすすめです。
URLにすべての設定情報が埋め込まれているので、チームメンバーへの共有も簡単です。
設定手順
- CloudWatchメトリクス→EBS→ボリューム別メトリクスでボリュームIDを検索
-
VolumeReadOps
,VolumeWriteOps
,VolumeReadBytes
,VolumeWriteBytes
を選択 - 統計は
合計
、期間は1分
を選択 - 数式を追加 → 空の式で始まる を選択
-
(VolumeReadOps+VolumeWriteOps)/60
と(VolumeReadBytes+VolumeWriteBytes)/60
の式を設定- 各メトリクスが60秒の合計値になっているので、1秒あたりにするために60で割ります
- 式以外のチェックを外して非表示に
- Y軸をIOPSとスループットで左右に分ける
- IOPSはk, スループットはmと単位が違うので、Y軸は分けたほうが見やすくなります
↓こちらVolumeIdleTimeの1枚目と同じ時間で設定した例です↓
こうして確認することで、同じVolumeIdleTimeがゼロの時間(大体右半分)でも、
IOPSやスループットには差があることがわかります。
そして、どちらも上限値に達しておらず余裕があるなら、
闇雲にIOPSやスループットを上げてもパフォーマンスは改善してくれません。
※ディスク性能の要素としては、EBS用のネットワーク帯域もありますが、今回は割愛してます
パフォーマンス改善に向けたチューニング
ここまでで、VolumeIdleTime
がゼロというのはディスク性能上限に達したという意味ではなく、
あくまでIOPSやスループットに着目するべき、というのがわかりました。
そして、パフォーマンスに問題があるにも関わらず、IOPSやスループットに余裕があるのであれば、
まず性能を十分に使い切れるように EBS以外の要素をチューニングする必要があります。
十分に使い切れるようになった後は、IOPSとスループットを上げてさらにパフォーマンスを改善できます。
チューニングについて、一般的には「I/O処理の並列化」、「I/Oサイズを大きくする」といった改善策がありますが、
使われているOSやミドルウェアによって対応は千差万別です。
自分がDBのパフォーマンス問題に取り組んだ際には、
OSとミドルウェアのレイヤーにボトルネックがあり読み書き速度が遅くなっていました。
そのボトルネックを取り除くことでIOPSとスループットが上限に達するようになり、
その後のIOPSとスループット増強で飛躍的にパフォーマンスが改善しました。
終わりに
EBSのVolumeIdleTime
がゼロだが、IOPSやスループットが上限に達していない謎が解けたでしょうか。
ディスクのパフォーマンス改善にあたっては、多数のメトリクスに惑わされず、
正しい数値に焦点を合わせてチューニングをしていってください。