OpenStack+KVMのCPUオーバーヘッド調査

調べる気になった事の発端は、Cinder+Cephのボリュームに対してMySQLのtpccベンチマークを取ってみた時に、vCPU=1 でVM内では CPU : 100% なのに、KVMプロセスのCPUが 300% を超えているのを見つけたことでした。

KVMは仮想環境なので当然オーバーヘッドが存在するのは覚悟済みですが、想像以上にホストOS上でCPUを食っていたために、良い子の私は地道に調べ始めるのでした。



検証環境

CPUとメモリ

ホストOSのcpuinfoの表示ですが
  • Intel(R) Xeon(R) CPU E5-2630L 0 @ 2.00GHz
  • VMだとこう
  • Intel Xeon E312xx (Sandy Bridge)
  • まぁほどほどに最近の、お値打ち価格になってきた低電力版なナイスCPUです。

    VMへは 1~4vCPU 割り当てて検証しています。
    VMに割り当てたメモリは全て 2GB にしました。

    KVMのオプション

    今回特に気にしたのがKVMのオプションで、OpenStackで作ったVMは
  • 1vCPU : -smp 1,sockets=1,cores=1,threads=1
  • 2vCPU : -smp 2,sockets=2,cores=1,threads=1
  • 4vCPU : -smp 4,sockets=4,cores=1,threads=1

  • このようなオプションになり、smpとsocketsが見たままで、coresとthreadsが固定になります。cores, threadsが気になったのですが、この辺の良い説明が見つからなかったし、OpenStackで利用する限りは変動しないようなので今回は気にしないコトにしました。

    調査内容は実質 KVM に対するものですが、利用環境はOpenStackであり、KVMオプションの調整に限界があるため、OpenStackにおける~ という意味であえてタイトルを OpenStack+KVM にしています


    virsh vcpuinfo

    実際にどのCPU(スレッド)を利用しているかは、

    で確認できるのですが、どうやらCPUスレッドは固定ではなく可変なので、同じCPU番号だったら…といったことは今回は考えないことにしました。ってのと、同時に負荷をかけるクライアント/サーバVMは極力別ホストOSで動かすとか適当な配慮をしました。


    CPU (姫野ベンチマーク)

    インストール

    VMに入れます。

    実行

    -np にparamset.shと同じ並列数を指定して実行。

    結果

    MFLOPSの取得回数は3回以上を平均し、HostのCPUは最大値をとっています。

    vCPU MFLOPSVM CPUHost CPU Host MFLOPS
    1 2004.7100%103% 2016.0
    2 3777.6200%203% 3803.0
    4 7147.3400%403% 7148.7

    まとめ

  • CPUとメモリの処理のみならば、KVMは数%のオーバーヘッドで済むようです
  • すなわち、1vCPU : 100% の性能は保証されている可能性大(※他のVMとCPU番号が被ったときは知らん)
  • VMでvCPU数以上のプロセス数を並列動作させてもホスト上の上限は守られました
  • MFLOPS値は並列度を増やすほどに合計性能が減少しているようにみえますが、ホストOSで計測してもほぼ同じ値だったのでKVMのせいではなく単に並列処理の問題のようです


  • UnixBench

    なんとなく計測してみたけど、処理のタイミングや処理内容がパラパラとして今回の確認事項には合わなかったので省略。


    Disk I/O (fio)

    対象デバイスは、HDDのRAID10を直接利用しています。
    Cephでもやりましたが、負荷のかかり方が不安定なので省略します。

    インストールと実行

    結果

    vCPU と numjobs を変動させて、VMでのIOPS、それとVMとHost両方のCPU利用率とI/O waitを計測しました。
    ただ、VMとHostの計測タイミングは完全に一緒ではないので、バラつきはあります…

    VMで実行
    VM Host
    vCPUnumjobs IOPSCPUiowait CPUiowait
    11 279114.983.6 9170.6
    12 244216.680.9 8575.0
    14 221612.987.9 5179.0
    22 204621.677.9 9584.1
    24 227615.785.0 61142.6
    28 215023.6101.0 88133.1
    44 205111.489.8 5282.8
    48 192712.1118.6 52146.7
    416 139915.2322.6 55134.9
    Hostで実行
    Host
    vCPUnumjobs IOPSCPUiowait
    241 65171570.9
    242 852832137.4
    244 456123196.3
    248 290119435.9

    まとめ

  • VM実行の際の、VMとHostのCPUを比較すると、40~70%程度 のオーバーヘッドがあります
  • VMとHostで実行したIOPSを比較すると、VMのIOPSは 70~30%程度 に落ち込んでいます
  • 以上から、VMにおけるディスクの利用には、CPUの大きなオーバーヘッドと、IOPS性能の劣化が伴うとわかります


  • ネットワーク (Iperf)

    Iperfを使って、ネットワークトラフィックを垂れ流してみます。
    ネットワークは 1Gbps で構築しています。

    インストールと実行

    結果

    Client側のvCPUは4で、並列数1~4で実行。
    Server側はCPUボトルネックにならないように8vCPUのVMで受信しました。

    iperfの並列
    CPU利用率(%) VM (iperf) Host (kvm)
    Mbpsparallel ClientServer ClientServer
    9301 10.350.3 102163
    9302 15.351.2 124165
    9304 12.088.2 108177
    Bandwidthの上限値変更
    CPU利用率(%) VM (iperf) Host (kvm)
    転送速度(Mbps) ClientServer ClientServer
    50 1.349 12.657
    100 2.350 14.361
    200 3.353 17.668
    400 5.765 44.5105
    800 9.687 63.5152

    まとめ

  • 並列数はさほどCPU利用率に影響なく、Bandwidthに大きく影響を受けるようです
  • トラフィックの増加に応じて 10~115% のCPUオーバーヘッドがKVMに発生するようです
  • Client/Serverどちらもなので、IN/OUT の違いはないようです
  • 10Gbpsだとどうなるかとても気になっています!


  • MySQL tpcc

    この計測は、様々な要素が交じってアレなので結果の詳細を書くのはやめておきます。
    なので、インストールと実行手順だけ書いておきます。

    インストール

    実行

    結果

    詳細は省きますが、1vCPUのVMにおいて、KVMプロセスが 280~380% のCPU利用率になることを確認できます。


    まとめ

    KVMのCPUオーバーヘッドは、
    CPU/メモリには微量しか認められませんが、
    ディスクとネットワークの利用には大きくとられることがわかりました。

    VMのCPU以外にも、VM⇔Host間のデータの転送時間といったものもあるでしょうし、
    HostではNovaComputeを筆頭にコンポーネントが色々動いています。

    …などを踏まえて、Host当たりのVMの数やvCPUの数を調整することになりますが、全VMがフル稼働することを想定してしまうと、普段だいぶ余力を残すことになり無駄なので、運用/Quota/その他制限 を探してある程度の保証と検知をする仕組みを確立したいところです。

    ……が、既に商用利用しているところもあるので、この辺の運用ポリシーを聞いてみたいですね!