調べる気になった事の発端は、Cinder+Cephのボリュームに対してMySQLのtpccベンチマークを取ってみた時に、vCPU=1 でVM内では CPU : 100% なのに、KVMプロセスのCPUが 300% を超えているのを見つけたことでした。
KVMは仮想環境なので当然オーバーヘッドが存在するのは覚悟済みですが、想像以上にホストOS上でCPUを食っていたために、良い子の私は地道に調べ始めるのでした。
検証環境
CPUとメモリ
ホストOSのcpuinfoの表示ですがVMへは 1~4vCPU 割り当てて検証しています。
VMに割り当てたメモリは全て 2GB にしました。
KVMのオプション
今回特に気にしたのがKVMのオプションで、OpenStackで作ったVMはこのようなオプションになり、smpとsocketsが見たままで、coresとthreadsが固定になります。cores, threadsが気になったのですが、この辺の良い説明が見つからなかったし、OpenStackで利用する限りは変動しないようなので今回は気にしないコトにしました。
調査内容は実質 KVM に対するものですが、利用環境はOpenStackであり、KVMオプションの調整に限界があるため、OpenStackにおける~ という意味であえてタイトルを OpenStack+KVM にしています
virsh vcpuinfo
実際にどのCPU(スレッド)を利用しているかは、
1 2 |
virsh list virsh vcpuinfo <id> |
で確認できるのですが、どうやらCPUスレッドは固定ではなく可変なので、同じCPU番号だったら…といったことは今回は考えないことにしました。ってのと、同時に負荷をかけるクライアント/サーバVMは極力別ホストOSで動かすとか適当な配慮をしました。
CPU (姫野ベンチマーク)
インストール
VMに入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# パッケージ # - lhasa は lha のため # - mpich2 は mpicc のため apt-get install lhasa mpich2 # ソース取得 cd /usr/local/src mkdir Himeno cd Himeno wget http://accc.riken.jp/secure/4514/cc_himenobmtxp_mpi.lzh lha e cc_himenobmtxp_mpi.lzh # 準備 cp Makefile.sample Makefile chmod +x paramset.sh # 数字は実行時の並列数。1,2,4を用意 for i in 1 2 4 do ./paramset.sh M 1 1 $i make mv bmt p$i.bmt make clean done |
実行
-np にparamset.shと同じ並列数を指定して実行。
1 2 3 |
mpirun -np 1 ./p1.bmt # vCPU=1 のVMで mpirun -np 2 ./p2.bmt # vCPU=2 のVMで mpirun -np 4 ./p4.bmt # vCPU=4 のVMで |
結果
MFLOPSの取得回数は3回以上を平均し、HostのCPUは最大値をとっています。vCPU | MFLOPS | VM CPU | Host CPU | Host MFLOPS |
1 | 2004.7 | 100% | 103% | 2016.0 |
2 | 3777.6 | 200% | 203% | 3803.0 |
4 | 7147.3 | 400% | 403% | 7148.7 |
まとめ
UnixBench
なんとなく計測してみたけど、処理のタイミングや処理内容がパラパラとして今回の確認事項には合わなかったので省略。Disk I/O (fio)
対象デバイスは、HDDのRAID10を直接利用しています。Cephでもやりましたが、負荷のかかり方が不安定なので省略します。
インストールと実行
1 2 3 4 5 6 |
apt-get install fio mkdir /tmp/fio # numjobs 1~4 で実行 fio --name=test --group_reporting --direct=1 --rw=randwrite \ --bs=16k --directory=/tmp/fio/ --size=512M --numjobs=4 |
結果
vCPU と numjobs を変動させて、VMでのIOPS、それとVMとHost両方のCPU利用率とI/O waitを計測しました。ただ、VMとHostの計測タイミングは完全に一緒ではないので、バラつきはあります…
VMで実行
VM | Host | |||||
vCPU | numjobs | IOPS | CPU | iowait | CPU | iowait |
1 | 1 | 2791 | 14.9 | 83.6 | 91 | 70.6 |
1 | 2 | 2442 | 16.6 | 80.9 | 85 | 75.0 |
1 | 4 | 2216 | 12.9 | 87.9 | 51 | 79.0 |
2 | 2 | 2046 | 21.6 | 77.9 | 95 | 84.1 |
2 | 4 | 2276 | 15.7 | 85.0 | 61 | 142.6 |
2 | 8 | 2150 | 23.6 | 101.0 | 88 | 133.1 |
4 | 4 | 2051 | 11.4 | 89.8 | 52 | 82.8 |
4 | 8 | 1927 | 12.1 | 118.6 | 52 | 146.7 |
4 | 16 | 1399 | 15.2 | 322.6 | 55 | 134.9 |
Hostで実行
Host | ||||
vCPU | numjobs | IOPS | CPU | iowait |
24 | 1 | 6517 | 15 | 70.9 |
24 | 2 | 8528 | 32 | 137.4 |
24 | 4 | 4561 | 23 | 196.3 |
24 | 8 | 2901 | 19 | 435.9 |
まとめ
ネットワーク (Iperf)
Iperfを使って、ネットワークトラフィックを垂れ流してみます。ネットワークは 1Gbps で構築しています。
インストールと実行
1 2 3 4 5 6 7 8 |
apt-get install iperf # Server側で実行 # TCP Bandwidthの制限はないので、-w でWindow sizeを変えることで転送速度を調整 iperf -s # Client側で実行。-P は並列数。-t は実行時間秒 iperf -c 192.168.0.xx -P4 -t 30 |
結果
Client側のvCPUは4で、並列数1~4で実行。Server側はCPUボトルネックにならないように8vCPUのVMで受信しました。
iperfの並列
CPU利用率(%) | VM (iperf) | Host (kvm) | |||
Mbps | parallel | Client | Server | Client | Server |
930 | 1 | 10.3 | 50.3 | 102 | 163 |
930 | 2 | 15.3 | 51.2 | 124 | 165 |
930 | 4 | 12.0 | 88.2 | 108 | 177 |
Bandwidthの上限値変更
CPU利用率(%) | VM (iperf) | Host (kvm) | ||
転送速度(Mbps) | Client | Server | Client | Server |
50 | 1.3 | 49 | 12.6 | 57 |
100 | 2.3 | 50 | 14.3 | 61 |
200 | 3.3 | 53 | 17.6 | 68 |
400 | 5.7 | 65 | 44.5 | 105 |
800 | 9.6 | 87 | 63.5 | 152 |
まとめ
MySQL tpcc
この計測は、様々な要素が交じってアレなので結果の詳細を書くのはやめておきます。なので、インストールと実行手順だけ書いておきます。
インストール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
cat > /etc/apt/sources.list.d/percona.list << __EOT__ deb http://repo.percona.com/apt wheezy main deb-src http://repo.percona.com/apt wheezy main __EOT__ apt-get update apt-get install percona-server-server-5.5 percona-server-client-5.5 apt-get install bzr cd /usr/local/src/ mkdir bazaar cd bazaar/ bzr init bzr branch lp:~percona-dev/perconatools/tpcc-mysql cd tpcc-mysql/src/ make all mysqladmin create tpcc -p cd /usr/local/src/bazaar/tpcc-mysql mysql -uroot -p -D tpcc < create_table.sql mysql -uroot -p -D tpcc < add_fkey_idx.sql |
実行
1 2 |
./tpcc_load localhost tpcc root password 2 ./tpcc_start -h localhost -P 3306 -d tpcc -u root -p password -w 2 -c 3 -r 30 -l 1800 |
結果
詳細は省きますが、1vCPUのVMにおいて、KVMプロセスが 280~380% のCPU利用率になることを確認できます。まとめ
KVMのCPUオーバーヘッドは、CPU/メモリには微量しか認められませんが、
ディスクとネットワークの利用には大きくとられることがわかりました。
VMのCPU以外にも、VM⇔Host間のデータの転送時間といったものもあるでしょうし、
HostではNovaComputeを筆頭にコンポーネントが色々動いています。
…などを踏まえて、Host当たりのVMの数やvCPUの数を調整することになりますが、全VMがフル稼働することを想定してしまうと、普段だいぶ余力を残すことになり無駄なので、運用/Quota/その他制限 を探してある程度の保証と検知をする仕組みを確立したいところです。
……が、既に商用利用しているところもあるので、この辺の運用ポリシーを聞いてみたいですね!