绑核原理
CPU绑定实际上是Libvirt通过CGroup来实现的,通过CGroup直接去绑定KVM虚拟机进程也可以。通过CGroup不仅可以做CPU绑定,还可以限制虚拟机磁盘、网络的资源控制,本书第6章将详细介绍CGroup在KVM虚拟化中的使用。
绑核带来的影响
1、当系统内VM所需的vCPU总数少于物理CPU的核数(包括超线程Core)时,虚拟化管理系统为vCPU分配的资源不超过一个物理CPU核。 vCPU与物理核的分配关系可以是绑定的,也可能是动态的。
比如服务器有20个核心,你创建了2个VM,每个VM 4个vCPU,那么这两个VM最多能够使用服务器的8个核心。
2、当系统内的VM所需要的vCPU核大于物理CPU核数时,虚拟化管理系统首先按照时间片轮流调度一遍,然后如果还有剩余的CPU资源,则给所需要的vCPU。 比如系统配置了40个vCPU,只有20个物理核。那么平均每个vCPU获取一个核心50%的资源。由于一些VM忙,一些VM空闲,虚拟化系统会在一个调度周期内,划分出若干时间片,轮流给每个vCPU使用。忙的vCPU可以使用完整个时间片,而闲的vCPU用不完整个时间片,会提前释放资源。这样在一个调度周期内,对每个vCPU都调度一遍后还有空闲的时间,调度器会把用这剩余的资源去调度忙的vCPU。 这样兼顾公平和效率。 这中调度算法具体下来,大致是如下效果:系统有1个CPU 2.0 Ghz,两个VM,分配1个vCPU。 如果VM1 和 VM2都忙,那么各自相当于拥有一个1.0 Ghz的CPU。 如果VM1很忙,VM1只需要 500Mhz的处理能力,那么在VM1看来,相当于暂时获得了 1.5Ghz的处理器。
3、通过对Xen的测试,系统所有虚拟机的vCPU的总数目小于和等于CPU核数时,VM的性能是比较稳定的。 VM的vCPU基本上绑定到了一个CPU核。 当vCPU数目大于物理核数时,VM的性能稳定性变差。
绑核方法
在宿主机操作系统启动时将用于虚拟机的CPU独立出来,使其上只运行vCPU线程,QEMU进程和少数的管理进程。设置方法即是在内核启动参数中加入: isolcpus=0,1 例如在grub.cfg下面的配置如下:
menuentry 'Fedora (3.13.6-200.fc20.x86_64) 20 (Heisenbug)' --class fedora --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.13.4-200.fc20.x86_64-advanced-5bcef32f-430b-4d74-beaa-4fcfccc438f9' { ...... linux /vmlinuz-3.13.6-200.fc20.x86_64 root=UUID=5bcef32f-430b-4d74-beaa-4fcfccc438f9 ro vconsole.font=latarcyrheb-sun16 rhgb quiet LANG=zh_CN.UTF-8 isolcpus=0,1 initrd initramfs-3.13.6-200.fc20.x86_64.img }
使用taskset命令将vCPU线程绑定到指定的物理CPU。例如,某虚拟机的qemu进程及两个vCPU线程如下:
[root@kelvin ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep root 4706 3629 4706 1 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm root 4706 3629 4708 1 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm root 4706 3629 4709 0 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
若要将线程ID为4709的vCPU从CPU0绑定到CPU2上执行,可使用如下命令: #taskset -p 0x4 4709 -p后面接的是物理CPU的掩码,其二进制表示从最低位到最高位分别表示第0个物理CPU到最后一个物理CPU,若二进制表示为1,则表示某线程可以在该物理CPU上运行,若为0,则不能。上面的命令的含义就是,线程ID为4709的线程(vCPU)只能在第2个(从0开始编号)物理CPU上运行。执行上述命令的结果如下:
[root@kelvin ~]# taskset -p 0x4 4709 pid 4709's current affinity mask: f pid 4709's new affinity mask: 4 [root@kelvin ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep root 4706 3629 4706 3 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm root 4706 3629 4708 0 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm root 4706 3629 4709 2 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
线程ID为4709的vCPU已经在编号为2的物理CPU上运行了。
Taskset和vcpupin区别
Taskset是以task(也就是虚拟机)为单位,也就是以虚拟机上的所有cpu为一个单位,与物理机上的cpu进行绑定,它不能指定虚拟机上的某个vcpu与物理机上某个物理cpu进行绑定,其粒度较大。
Vcpupin命令就可以单独把虚拟机上的vcpu与物理机上的物理cpu进行绑定。
比如vm1有4个vcpu(core),物理机有8个cpu(8个core,假如每个core一个线程),taskset能做到把4个vcpu同时绑定到一个或者多个cpu上,但vcpupin能把每个vcpu与每个cpu进行绑定。
查看哪个进程在哪个CPU上运行:ps -eopid,args,psr|grep 95090
[root@test ~]# ps -eopid,args,psr|grep 95090
95090/usr/bin/qemu-system-test 8
95091 [vhost-95090] 80
161336 grep --color=auto 95090 72




