在KVM虚拟机中运行mysql,发现与ESX虚拟机中比较,性能有些差。用sysbench测试KVM虚拟机中的mysql,TPS刚刚到1500级别。性能如图:
使用perf命令跟踪KVM虚拟机对应的进程,情况如下:
从图中可以看出,这台虚拟机的page_fault占比较高,其次是__GI__ioctl,而sys_poll虽然占比高,却无需关注,因为即使虚拟机是空闲状态,sys_poll也会高。
使用perf跟踪kvm事件可以看到情形如图:
从图中来看,发生次数频繁的事件主要是kvm_page_fault,kvm_apic,kvm_pio,kvm_entry,kvm_exit,kvm_apic_ipi,kvm_apic_accept_irq。
kvm_entry和kvm_exit是进入退出虚拟机状态的事件,这两个事件主要是由其它事件引发的副作用,不需过多关注。
kvm_apic_ipi,kvm_apic_accept_irq是中断相关的,也无需过多关注。
剩下的需要关注的是kvm_page_fault,kvm_apic,kvm_pio
先来看kvm_apic,kvm_pio。使用perf跟踪kvm_apic,kvm_pio,如图:
从图中可以看出,相关的IO端口主要是0xc090和APIC_ICR
APIC_ICR是中断相关的,无需关注。
执行命令virsh qemu-monitor-command vm_name --hmp --cmd "info mtree",输出如下
可知0xc090对应的是virtio-pci
在虚拟机内部执行命令cat /proc/ioports,可知端口范围c080-c0bf对应的PCI是0000:00:08.0结果如下
在虚拟机内部执行lspci命令,可知PCI 0000:00:08.0对应的设备为00:08.0 SCSI storage controller: Red Hat, Inc Virtio block device。lspci命令结果如下
查看虚拟机的配置文件,有如下内容,也可确认0xc090对应的是存储设备
从上述过程可知,性能调优不需要过多关注KVM事件kvm_apic,kvm_pio,剩下的就是分析事件kvm_page_fault了。
kvm_page_fault频繁,是内存方面的问题。物理机中执行free -m命令,发现内存是足够的。估计有可能是NUMA方面的原因。
查看系统NUMA情况:
从lscpu结果来看,系统中存在两个NUMA结点。
查看虚拟机CPU和内存的NUMA分布情况。虚拟机名称是testmysql,配置情况是4核8G,对应的进程PID是2783217。
查看CPU分布:
从结果可以知道虚拟机CPU主要分布在node1上。
查看内存分布(虚拟机对应的进程PID是2783217):
虚拟机的CPU分布在node1上,而内存却分布在node0上。性能肯定会下降。再看看各个node的内存使用情况。
node0的:
node1的:
从结果看,各个node的空闲内存是足够8G的(注意虚拟机本来就主要运行在node0内存上,node0还剩下6G的内存)。
接下来,将虚拟机的内存和CPU绑定在同一节点上运行,同时开启hugepage。
node1上空闲内存多些,在node1上建立hugepage。
同时,在虚拟机配置文件中增加hugepage配置,将虚拟cpu绑定在node1上。
关闭虚拟机后重新启动。
在虚拟机中启动测试,使用perf查看kvm事件:
kvm:kvm_page_fault事件只有340,kvm_entry和kvm_exit也降下来了。
下面是虚拟机中测试结果:
性能达到了1777。
现在看下内存在物理机NUMA中的分布情况(重启后虚拟机进程PID为3159995):
虚拟内存分布在了node1上。
由于虚拟机中磁盘IO使用了pagecache,而物理机中也使用了pagecache,可以让虚拟机中磁盘io不使用pagecache。设置虚拟磁盘IO调度方式为noop,并再次测试:
性能达到了1884。
经过以上调试,性能从一开始的1500到了1884。