- http://docs.redhat.com/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/ch-Subsystems_and_Tunable_Parameters.html
- http://www.kernel.org/doc/Documentation/devices.txt
- /usr/share/doc/kernel-*/Documentation/cgroups/
redhatのcgroupのdocument見ていてDisk I/Oの帯域制限できたら完璧なのになー、と思っていたんだけど、cgroup/blkio/ 内のファイルを見ていたらたらblkio.throttle.* というそれっぽいファイルを発見。最新のkernelのdocument内にも見つけたので、redhatの日本語documentが古いだけかな。
# ls /cgroup/blkio/ blkio.io_merged blkio.reset_stats blkio.throttle.write_bps_device libvirt blkio.io_queued blkio.sectors blkio.throttle.write_iops_device notify_on_release blkio.io_service_bytes blkio.throttle.io_service_bytes blkio.time release_agent blkio.io_service_time blkio.throttle.io_serviced blkio.weight tasks blkio.io_serviced blkio.throttle.read_bps_device blkio.weight_device blkio.io_wait_time blkio.throttle.read_iops_device cgroup.procs
- blkio.throttle.io_service_bytes
- blkio.throttle.io_serviced
- blkio.throttle.read_bps_device
- blkio.throttle.read_iops_device
- blkio.throttle.write_bps_device
- blkio.throttle.write_iops_device
libvirt (kvm) 仮想マシンのdisk I/O を制限する例
仮想マシンのイメージファイルを仮想ホストの/dev/sda に置いているとする。blkio サブシステムではデバイスごとにパラメータを設定するので、まず /dev/sda のmajor, minor 番号を調べる。
(ここで言っているデバイスは仮想マシン上の/dev/sda, /dev/vda などではなく、ホストOS上のデバイス)
# ls -l /dev/sda brw-rw---- 1 root disk 8, 0 4月 15 16:10 2012 /dev/sda
=> major 8, minor 0
cgconfig を有効にしている状態で、libvirtdを起動すると/cgroup/*/libvirt/qemu/test1 のグループを作成してtasksにqemu-kvm その他関連するpidを書き込んでくれる。これを利用して、/etc/cgconfig.conf に
group libvirt/qemu/test1 { blkio { blkio.throttle.read_bps_device = "8:0 20000000"; blkio.throttle.write_bps_device = "8:0 20000000"; } }
これを書いてcgconfig restart 後にlibvirtd を再起動、仮想マシン test1 を起動。
# service cgconfig restart # service libvirtd restart # virsh start test1
$ more /cgroup/blkio/libvirt/qemu/test1/tasks 3218 ### qemu-kvm のpid 等が書き込まれていることを確認 $ more /cgroup/blkio/libvirt/qemu/test1/blkio.throttle.*_bps_device :::::::::::::: /cgroup/blkio/libvirt/qemu/test1/blkio.throttle.read_bps_device :::::::::::::: 253:3 20000000 /cgroup/blkio/libvirt/qemu/test1/blkio.throttle.write_bps_device :::::::::::::: 253:3 20000000
この状態でvm test1 上からddを実行して、1Gのファイルを作成する。サイズは適当だけど割当てメモリに対して小さすぎるとバッファに載ってしまいそうなので、適当に大きいサイズで。
write
# virsh console test1 Connected to domain test1 エスケープ文字は ^] です Scientific Linux release 6.2 (Carbon) Kernel 2.6.32-220.el6.x86_64 on an x86_64 test1 login: root Password: Last login: Fri Apr 15 07:59:11 on tty1 # dd if=/dev/zero of=/tmp/hoge.dat bs=1M count=1000 1000+0 records in 1000+0 records out 1048576000 bytes (1.0 GB) copied, 49.221 s, 21.3 MB/s
ほぼ設定値通りの20MByte/secになった。ちなみにcgroupを設定していない状態だとwriteは120MByte/secぐらい出た
read
# time dd if=hoge.dat of=/dev/null bs=1M count=2048 2048+0 records in 2048+0 records out 2147483648 bytes (2.1 GB) copied, 2.61108 s, 822 MB/s real 0m2.619s user 0m0.004s sys 0m1.522s
822MB/sec !? 明らかに早すぎる。おかしい。キャッシュのせいだろう。ということで仮想マシンのバッファキャッシュをクリアして再挑戦。
# sync # echo 3 > /proc/sys/vm/drop_caches # echo 0 > /proc/sys/vm/drop_caches # time dd if=hoge.dat of=/dev/null bs=1M count=2048 2048+0 records in 2048+0 records out 2147483648 bytes (2.1 GB) copied, 2.76242 s, 777 MB/s real 0m2.775s user 0m0.003s sys 0m1.518s
777 MB。やっぱりまだ早い。うーん、readは制限きかない?と思ったところで、いやこれは仮想ホスト上でキャッシュしてるからだろうと推測して、仮想ホスト上でもキャッシュをクリア。
# sync # echo 3 > /proc/sys/vm/drop_caches # echo 0 > /proc/sys/vm/drop_caches
そして再度仮想マシン上でddを実行。
# time dd if=hoge.dat of=/dev/null bs=1M count=2048 2048+0 records in 2048+0 records out 2147483648 bytes (2.1 GB) copied, 106.986 s, 20.1 MB/s real 1m47.032s user 0m0.007s sys 0m2.288s
こちらも設定値とおり、ほぼ20Mbyte/secになった。
*1:実際にI/Oが集中して困るのはwriteのほうなので、readは制限しなくても良い or もっと緩い値でもいいかも