转载请附本文链接:https://blog.csdn.net/maxlovezyy/article/details/70336460
CPU通过硬中断获取硬件事件。每一个网卡的队列都会有一个中断号,当有数据流入的时候,会产生一个硬中断,linux的默认的策略是通过irqbalance这个服务分配网卡中断(考虑线上机器的系统都会是大于等于2.4 kernel),但是这个irqbalance可能并不好,所以我们自己配置以提升性能。
配置方法
-
停止系统本身的分配器
我在自己电脑ubuntu15上没有停止,但是我的配置策略也是生效的,可能是负载不够,还没轮得到irqbalance工作,也可能是irqbalance会按照配置来,不过无论如何还是要停止这个服务以确保百分百按我的配置来。
[root@sunchao31 /proc]# service irqbalance stop -
找到需要配置的硬件的中断号
[root@sunchao31 /proc]# cat /proc/interrupts
CPU0 | CPU1 | CPU2 | CPU3 | |||
---|---|---|---|---|---|---|
0: | 4865302 | 5084964 | 4917705 | 5017077 | IO-APIC-edge | timer |
… | … | … | … | … | … | … |
31: | 93707 | 106211 | 107988 | 93329 | IO-APIC-level | eth0 |
NMI: | 0 | 0 | 0 | 0 | ||
… | … | … | … | … | … | … |
MIS: | 0 |
表中的第1列是设备对应的中断号,最后一列是设备名,第6列是设备驱动信息。我们需要根据设备名找到网卡(队列),之后找到其中断号。比如这里就是**<31, …, eth0>**。
- 配置这个中断号的cpu亲缘性
在/proc/irq目录下存储着各个中断号配置的文件夹,里面有一个smp_affinity文件,它存储的内容是16进制的bit mask(位掩码),只要修改这里的掩码就行。掩码是最右端对应最小序号的cpu。
比如假如主机有4个核,那么:
echo 2 > /proc/irq/31/smp_affinity,则eth0的中断就只会发给cpu1,而echo F > /proc/irq/31/smp_affinity就配置了所有核(不建议这样做)。
如果核数超过了32,就需要用两段来表达,比如想配置上面的31号中断到64核机器的第1号核,需要这样:
echo “00000000,00000002” > /proc/irq/31/smp_affinity。
注意点
- 0号core尽量不要绑定,它会处理系统的好多中断。
- 网卡队列分散绑定到多核心,比如每一个网卡绑定到一个core上。
- 注意超线程,这种情况下都是两个线程对应一个core,要通过类似于lstopo的命令、
- 多个物理网卡,尽量把网卡的队列绑定到PCI-E链接的CPU socket之上的core上。
假如有20个核心,两个物理网卡,那么一般情况下是一个处理器的socket和PCI-E1连接,另一个处理器的socket和PCI-E2连接。其中一半core在一个处理器上,一半core在另一个处理器上。 - 查看对应关系的命令: lstopo或cat /proc/cpuinfo和lspci结合着看就ok了。
- 如果是单队列网卡,可以通过rps/rfs技术模拟多队列以提高性能。
- 硬盘中断也一样。你也可以特定场合下把一部分核配给网卡中断,一部分核配给硬盘中断等其他中断。
- 配置你的服务器之前最好先看明白中断分布,如果你的服务器开启了irqbalance,没准它工作的很好呢,虽然好多都说它不好!
参考链接
rethat smp_affinity
person blog
round-robin style interrupt delivery is not a good idea
Balancing Hardware Interrupts
Introduction to Linux Interrupts and CPU SMP Affinity