仮想環境でマシンを動かしている時、隣のVMが高負荷状態だったりすると、
自分のVMがその煽りを食ってパフォーマンスがダウンすることがあります。
(よくあることですね)
今回は、一番(?)単純化した図式で、
どんな影響が出るのか、数字で見てみようと思います。
やることとしては、MainサーバーとSubサーバーを用意し、
その上でMySQLを動かしているところに、
APサーバーからそれぞれにsysbenchで負荷をかける、
という感じです。
Mainには180秒負荷をかけ、
テスト開始から少し(45秒)してからSubにも60秒負荷をかけ、
その時にMainのTPS(MySQL観点)はどうなるかを見ます。
TPSはsysbenchから、awaitはiostatから取ります。
環境は以下です。
ハイパーバイザー: ESXi 5.5 各VMへのI/O帯域制限なし Mainサーバー: CentOS 6.5 MySQL 5.7.20 Subサーバー: CentOS 7.1 MySQL 5.7.19 APサーバー: sysbench 1.0.9
結果はこんな感じです。
(一番上はリファレンスのためにSubの負荷なしでの状態をとりました)
一目瞭然、影響をモロに受けているのが見て取れます。
元々、1インスタンスだけでもIOを最大限使っていたところに、
さらに横のVMがIO負荷をかけたら、
そりゃあTPSはこうなるよね、というお話です。
150秒以降にTPSが低下していますが、
これはSubインスタンスでI/O要求を出していたことに由来していました。
I/O要求の犯人まで特定できていないのですが、
sysbenchでの負荷は止めていたので、
ib_logfileのフラッシュとか、
ファイルシステムキャッシュ関連とか、
その辺かなぁ?と思っています。
さらに、Average Waitの悪化が見て取れ、
I/Oのキューが長くなっていることがわかります。
また、何故かわかりませんが、
後発のSubサーバーの方がAverage Waitが長くなる傾向にありました。
MainとSubでかけた負荷は同じ(MySQLのメモリ設定などは多少違うのですが)なので、
1インスタンス→2インスタンスなんだからTPSは半分くらいで済むかと思いきや、
それよりもはるかに悪く、1/4程度になっています。
Mainのみで負荷をかけていた時は、
MainのOSで見える%utilは90%前後を推移していましたが、
Subで負荷をかけている時間帯は98%前後と、ほぼ100%に張り付いている状態だったので、
もしかしたらリトルの法則でこの現象(TPSが1/4になったこと)は
説明がつくのかな?と思いました。
ただ、そうだとすると、
1インスタンスでIO待ちがでるほど負荷をかけた状態でも、
実はまだ%utilには10%ほどの余裕があり、
この余裕は他VMが負荷をかけることによって食いつぶされる、
という事になります。
そんなことってあるんですかね・・・?
この辺の理由については後日もう少し調べてみたいです。
なお、サービスタイム(svctm)についても見るのが一般的なように思えましたが、
svctmについては、iostatのmanページに「信用するな」と明記されていたので、
メトリクスには採用しないことにしました。
iostatのmanページ:
The average service time (in milliseconds) for I/O requests that were issued to the device. Warning! Do not trust this field any more. This field will be removed in a future sysstat version.
今度時間があれば、ESXiでIO帯域制限をかけた場合には
ちゃんと横VMの影響を受けなくなるのか、
というのも調べてみたいと思います。