网卡中断与软中断

1. mpstat -P ALL 1  或 mpstat -I SUM -P ALL 1(有的机器得用这个命令),top命令也可以               显示软中断发生在cpu0 和cpu1 , 其中主要发生在cpu0;    

2. sar -n DEV 1         显示 网络读写发生在eth1

3. cat /proc/interrupts | grep eth1    通过这个可以查看网卡队列数目,也可以查看哪个cpu占用的软中断

Linux内核在性能方面已经经历了很长一段时间的考验,尤其是2.6/3.x内核。然而,在高IO,尤其是网络方面的情况下,对中断的处理可能成为问题。我们已经 在拥有一个或多个饱和1Gbps网卡的高性能系统上发现过这个问题,近来在有许多小包并发(大约10000packets/second)超载的虚拟机上 也发现了这个问题。

原因很清楚:在最简单的模式中,内核通过硬件中断的方式来处理每个来自于网卡的包。但是随着 数据包速率的增长,带来的中断渐渐超过了单个cpu可处理的范围。单cpu概念很重要,系统管理员对此往往认识不足。在一个普通的4-16核的系统中,因 为整体cpu的使用率在6-25%左右并且系统看上去很正常,所以一个过载的内核很难被发现,。但是系统将运行很慢,并且会在没有告警,没有dmesg日 志,没有明显征兆的情况下严重丢包。

但是你使用top查看多个cpu模式(运行top,接着键入1)时,%si 列(系统中断)或者mpstat命令中 irq列(mpstat -P ALL 1),在一些繁忙的系统中你会发现中断明显很高,通过经进一步mpstat使用,你会看到哪个cpu或者哪个设备存在问题。

你需要一个较新版本的mpstat,可以运行-I 模式,用以列出irq负载,运行如下命令:

mpstat -I SUM -P ALL 1

超过5000/秒 有点繁忙, 1万-2万/秒相当高了。

运行如下命令来确认那个设备/项目导致负载:

mpstat -I CPU -P ALL 1 这个输出很难被阅读,但是你可以跟踪正确的列用来确认哪个中断导致负载,例如:15,19,995. 你也可以定义你想查看的cpu

mpstat -I CPU -P 3 1 # 3 在top,htop中可以定位不同的cpu。(top和mpstat都是从0开始,htop是从1开始计数)

记录下中断数,你就可以查看中断表 ,"cat /proc/interrupts" 找到mpstat's得到的数字,你可以发现是哪个设备在使用中断。这个文件也指示了使用该中断的#可以告诉你是什么导致过载。

需要做什么呢?

首先,确认你是否运行irqbalance,这个是nice守护进程它会自动在cpu间扩展中断。在繁忙的系统中很重要,尤其是两块网卡,因为默认cpu0 将处理所有中断,系统很容易过载。irqbalance扩散这些中断用以降低负载。为了性能最大化,你可以手动平衡这些中断将套接字和超线程共享内核分 散,但是通常没必要这么麻烦。

但是即使扩展了中断,某块网卡还是可能导致某一个cpu过载。这取决于你的网卡和驱动,但通常有两种有效的方法来防止这样的事情发生。

第一种是多网卡队列,有些Intel网卡就可以这么做。如果他们有4个队列,就可以有四个cpu内核同时处理不同的中断用以分散负载。通常驱动会自动这么做,你也可以通过mpstat命令来确认。

第二种,并且通常也是更加重要的,网卡驱动选项——'IRQ coalescing',中断请求合并。这个选项有着强大的功能,允许网卡在调用中断请求前缓存数个数据包,从而为系统节约大量的时间和负载。

举个例子: 如果网卡缓存10个包,那么cpu负载将大约降低90%。这个功能通常用ethtool工具来控制,使用'-c/-C'参数,但是有些驱动要求在驱动初次 加载时就做好相关设置。如何设置需要查看本机文档。举个例子,有些网卡,譬如我们使用的Intel网卡,就有automatic模式可以根据负载自动做到 最优化。 最后,就像我们在虚拟机中看到的一些驱动,它们不支持多队列或者中断请求合并。这种情况下,一旦处理中断的cpu繁忙,就会产生性能瓶颈,除非你更换设备或者驱动。 这是一个复杂的区域,并不广为人知,但有些不错的技术真的可以提高繁忙系统的性能。此外,一些额外的针对性监控,可以帮助到查找和诊断这些难以发现的问题。

前些天发现XEN虚拟机上的Nginx服务器存在一个问题:软中断过高,而且大部分都集中在同一个CPU,一旦系统繁忙,此CPU就会成为木桶的短板。

在问题服务器上运行「top」命令可以很明显看到「si」存在异样,大部分软中断都集中在 1 号CPU上,其它的CPU完全使不上劲儿:

shell> top
Cpu0: 11.3%us,  4.7%sy,  0.0%ni, 82.5%id,  ...  0.8%si,  0.8%st
Cpu1: 21.3%us,  7.4%sy,  0.0%ni, 51.5%id,  ... 17.8%si,  2.0%st
Cpu2: 16.6%us,  4.5%sy,  0.0%ni, 77.7%id,  ...  0.8%si,  0.4%st
Cpu3: 15.9%us,  3.6%sy,  0.0%ni, 79.3%id,  ...  0.8%si,  0.4%st
Cpu4: 17.7%us,  4.9%sy,  0.0%ni, 75.3%id,  ...  1.2%si,  0.8%st
Cpu5: 23.6%us,  6.6%sy,  0.0%ni, 68.1%id,  ...  0.9%si,  0.9%st
Cpu6: 18.1%us,  4.9%sy,  0.0%ni, 75.7%id,  ...  0.4%si,  0.8%st
Cpu7: 21.1%us,  5.8%sy,  0.0%ni, 71.4%id,  ...  1.2%si,  0.4%st

查询一下软中断相关数据,发现主要集中在 NET_RX 上,猜测是网卡问题:

shell> watch -d -n 1 'cat /proc/softirqs'
                CPU0       CPU1       CPU2 ...       CPU7
      HI:          0          0          0 ...          0
   TIMER: 3692566284 3692960089 3692546970 ... 3693032995
  NET_TX:  130800410  652649368  154773818 ...  308945843
  NET_RX:  443627492 3802219918  792341500 ... 2546517156
   BLOCK:          0          0          0 ...          0
BLOCK_IOPOLL:      0          0          0 ...          0
 TASKLET:          0          0          0 ...          0
   SCHED: 1518716295  335629521 1520873304 ... 1444792018
 HRTIMER:        160       1351        131 ...        196
     RCU: 4201292019 3982761151 4184401659 ... 4039269755

补充:有一个查看中断(Interrupt)的top风格小工具 itop ,推荐试试。

确认一下宿主机上的网卡信息,发现其运行在单队列模式下:

shell> grep -A 10 -i network /var/log/dmesg
Initalizing network drop monitor service
Intel(R) Gigabit Ethernet Network Driver - version 3.0.19
igb 0000:05:00.0: Intel(R) Gigabit Ethernet Network Connection
igb 0000:05:00.0: eth0: (PCIe:2.5GT/s:Width x4) 00:1b:21:bf:b3:2c
igb 0000:05:00.0: eth0: PBA No: G18758-002
igb 0000:05:00.0: Using MSI-X ... 1 rx queue(s), 1 tx queue(s)
igb 0000:05:00.1: Intel(R) Gigabit Ethernet Network Connection
igb 0000:05:00.1: eth1: (PCIe:2.5GT/s:Width x4) 00:1b:21:bf:b3:2d
igb 0000:05:00.1: eth1: PBA No: G18758-002
igb 0000:05:00.1: Using MSI-X ... 1 rx queue(s), 1 tx queue(s)

接着确认一下网卡的中断号,因为是单队列,所以只有一个中断号 45:

shell> grep eth /proc/interrupts | awk '{print $1, $NF}'
45: eth0

知道了网卡的中断号,就可以查询其中断亲缘性配置「smp_affinity」:

shell> cat /proc/irq/45/smp_affinity
02

这里的 02 实际上是十六进制,表示 1 号CPU,计算方法如下(参考资料):

          Binary       Hex 
  CPU 0    0001         1 
  CPU 1    0010         2
  CPU 2    0100         4
+ CPU 3    1000         8
  -----------------------
  both     1111         f

说明:如果 4 个CPU都参与中断处理,那么设为 f;同理 8 个CPU的就设置成 ff:

shell> echo ff > /proc/irq/45/smp_affinity

此外还有一个类似的配置「smp_affinity_list」:

shell> cat /proc/irq/45/smp_affinity_list
1

两个配置是相通的,修改了一个,另一个会跟着变。不过「smp_affinity_list」使用的是十进制,相比较「smp_affinity」的十六进制,可读性更好些。

了解了这些基本知识,我们可以尝试换一个CPU试试看会发生什么:

echo 0 > /proc/irq/45/smp_affinity_list

再通过「top」命令观察,会发现处理软中断的CPU变成了 0 号CPU。

说明:如果希望多个CPU参与中断处理的话,可以使用类似下面的语法:

echo 3,5 > /proc/irq/45/smp_affinity_list
echo 0-7 > /proc/irq/45/smp_affinity_list

坏消息是对单队列网卡而言,「smp_affinity」和「smp_affinity_list」配置多CPU无效。

好消息是Linux支持RPS,通俗点来说就是在软件层面模拟实现硬件的多队列网卡功能。

首先看看如何配置RPS,如果CPU个数是 8 个的话,可以设置成 ff:

shell> echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus

接着配置内核参数rps_sock_flow_entries(官方文档推荐设置: 32768):

shell> sysctl net.core.rps_sock_flow_entries=32768

最后配置rps_flow_cnt,单队列网卡的话设置成rps_sock_flow_entries即可:

echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt

说明:如果是多队列网卡,那么就按照队列数量设置成 rps_sock_flow_entries / N 。

做了如上的优化后,我们再运行「top」命令可以看到软中断已经分散到了两个CPU:

shell> top
Cpu0: 24.8%us,  9.7%sy,  0.0%ni, 52.2%id,  ... 11.5%si,  1.8%st
Cpu1:  8.8%us,  5.1%sy,  0.0%ni, 76.5%id,  ...  7.4%si,  2.2%st
Cpu2: 17.6%us,  5.1%sy,  0.0%ni, 75.7%id,  ...  0.7%si,  0.7%st
Cpu3: 11.9%us,  7.0%sy,  0.0%ni, 80.4%id,  ...  0.7%si,  0.0%st
Cpu4: 15.4%us,  6.6%sy,  0.0%ni, 75.7%id,  ...  1.5%si,  0.7%st
Cpu5: 20.6%us,  6.9%sy,  0.0%ni, 70.2%id,  ...  1.5%si,  0.8%st
Cpu6: 12.9%us,  5.7%sy,  0.0%ni, 80.0%id,  ...  0.7%si,  0.7%st
Cpu7: 15.9%us,  5.1%sy,  0.0%ni, 77.5%id,  ...  0.7%si,  0.7%st

疑问:理论上讲,我已经设置了RPS为ff,应该所有 8 个CPU一起分担软中断才对,可实际结果只有两个,有知道原因的请赐教,但是不管怎么说,两个总好过一个。

此外,因为这是一台Nginx服务器,所以通过「worker_cpu_affinity」指令可以配置Nginx使用哪些CPU,如此一来我们便可以绕开高负载的CPU,对性能会有一些帮助。

补充:如果服务器是NUMA架构的话,那么「numactl –cpubind」可能也会有用。

最后,推荐看看香草总结的一些关于软中断方面的资料工具,很全面。

猜你喜欢

转载自blog.csdn.net/nawenqiang/article/details/82854929
今日推荐