前天在项目中对一个准生产系统做压力的时候,发现在OS级别的CPU监控上有如下信息。
既然是中断高,那就查一下如下信息。cat /proc/interupts
从中断来看是
29: 62 0 0 0 0 0 0 0 0 2703014 0 117440 0 0 0 0 0 0 0 0 0 0 369323558 0 PCI-MSI-edge virtio0-input.0
这一条的第22个CPU中断累积最高。再佐证一下:
[root@主机A]# cat /proc/irq/29/smp_affinity_list
22
中断号29的CPU亲和性,确实是在CPU 22上。
再看一下软中断,cat /proc/softirqs
看到是NET-RX在第22个CPU上的中断累积值最高。
下面就接着查网卡信息,看是不是单队列网卡导致的。查下网卡信息lspci -vvv
看到物理网卡并是多队列网卡MSI-X。那为什么在系统上看到的是网卡接受消耗的sys CPU最高呢。接着来查一下这个网卡设备:
[root@主机A]# ethtool -i eth0
driver: virtio_net
version:
firmware-version:
bus-info: virtio0
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
bus-info也确实是virtio0,和在/proc/interrupts上看到的是一样的。既然确定是网卡设备,并且也看到了虚拟io,这里稍微提一下虚拟IO的逻辑。从硬件到硬件驱动,再到虚拟化出来的驱动,然后才到linux guest层,那这一层层的的查看是不是有错漏的地方呢。
note:下图仅是示意图。
回想那个lspci,是查硬件信息的。所以这个宿主机的网卡应该是没问题的,标准的多队列网卡。但是从guest linux上查看到时候,确实是网卡的接受导致了大量的sys CPU中断。
那就查一下guest层的网卡队列,看下到底是多少队列。
[root@主机A]# ll /sys/class/net/eth0/queues
总用量 0
drwxr-xr-x 2 root root 0 6月 3 15:21 rx-0
drwxr-xr-x 2 root root 0 6月 3 15:21 tx-0
确实是只有一个队列。可见是虚拟化这一层是有问题的。经与这个云服务器提供商沟通了之后,他们确定为是虚拟化这一层有了问题,他们会提供个更新包。
上周六,这个云服务器提供商尝试升级了一下虚拟化层的driver,但是升级失败。等他们升级成功后方可解决这个问题了。
经云服务厂商确定的升级步骤如下:
1,升级母机的kernel.tgz、qemu.tgz、libvirt_agent.tgz三个包。并重启。
2,在母机上修改之前已创建子机对应 配置文件/etc/vm/xxxx.xml (xxxx指子机的uuid),
具体改动为将xxxx.xml的:
<driver name='vhost' event_idx='on'/>
改为
<driver name='vhost' event_idx='on' queues='1'/>
如果子机CPU<=8,queues设置为CPU的数量;大于等于8,queues则设置为 8。之后执行virsh define /etc/vm/xxxx.xml使改动生效。
3,重启子机,将20170117161800_5fs6i_basic_linux_install.tar.gz上传到子机,解压缩 并执行install.sh。
4,最后登录子机查看ll /sys/class/net/eth0/queues。
升级后的网卡队列是:
问题解决。
过程中,我打算配置RPS的,可是尝试了几次,都没见到有明显的效果,CPU仍然是22用的最多。设置内容如下:
[root@主机A virtio0-input.0]# cat /sys/class/net/eth0/queues/rx-0/rps_cpus
ffffff
[root@主机A virtio0-input.0]# sysctl net.core.rps_sock_flow_entries=32768
net.core.rps_sock_flow_entries = 32768
[root@主机A-input.0]# sysctl -a |grep net.core.rps_sock_flow_entries
net.core.rps_sock_flow_entries = 32768
[root@主机A-input.0]# echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
[root@主机A virtio0-input.0]# cat /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
32768
有知道这些方法在虚拟化层Driver有问题的情况下是不是不生效,反正我这边是没试成功。如有和我环境一样的并且成功的也请不吝赐教。
性能分析就是这样一层又一层的关系。