在前阵子看到HelloDB的一篇文章“MySQL单机多实例方案”中提到:
因为单机运行多个实例,必须对网络进行优化,我们通过多个的IP的方式,将多个MySQL实例绑定在不同的网卡上,从而提高整体的网络能力。还有一种更高级的做法是,将不同网卡的中断与CPU绑定,这样可以大幅度提升网卡的效率。
于是,对“将不同网卡的中断与CPU绑定,这样可以大幅度提升网卡的效率”比较感兴趣,所以找了点资料了解一下。先总结如下:
1. 不同的设备一般都有自己的IRQ号码(当然一个设备还有可能有多个IRQ号码)
通过命令:cat /proc/interrupts查看
如:cat /proc/interrupts | grep -e "CPU\|eth4"
2. 中断的smp affinity在cat /proc/irq/$Num/smp_affinity
可以echo “$bitmask” > /proc/irq/$num/smp_affinity来改变它的值。
注意smp_affinity这个值是一个十六进制的bitmask,它和cpu No.序列的“与”运算结果就是将affinity设置在那个(那些)CPU了。(也即smp_affinity中被设置为1的位为CPU No.)
比如:我有8个逻辑core,那么CPU#的序列为11111111 (从右到左依次为#0~#7的CPU)
如果cat /proc/irq/84/smp_affinity的值为:20(二进制为:00100000),则84这个IRQ的亲和性为#5号CPU。
每个IRQ的默认的smp affinity在这里:cat /proc/irq/default_smp_affinity
另外,cat /proc/irq/$Num/smp_affinity_list 得到的即是CPU的一个List。
3. 默认情况下,有一个irqbalance在对IRQ进行负载均衡,它是/etc/init.d/irqbalance
在某些特殊场景下,可以根据需要停止这个daemon进程。
4. 如果要想提高性能,将IRQ绑定到某个CPU,那么最好在系统启动时,将那个CPU隔离起来,不被scheduler通常的调度。
可以通过在Linux kernel中加入启动参数:isolcpus=cpu-list来将一些CPU隔离起来。
参考资料:
http://kernel.org/doc/Documentation/IRQ-affinity.txt
http://kernel.org/doc/Documentation/kernel-parameters.txt
http://www.vpsee.com/2010/07/load-balancing-with-irq-smp-affinity/