多核下绑定网卡中断到不同CPU
问题描述:LVS做load balance时发现在并发达到1w+以后网卡中断只占用了一个CPU,最终导致此CPU的100%,性能再无法提升
cpu 未充分利用,单核使用达100%导致性能瓶颈
硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。现在的服务器上动不动就是多 CPU 多核、多网卡、多硬盘,如果能让网卡中断独占1个 CPU (core)、磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担、提高整体处理效率。
什么是中断
简单的说就是,每个硬件设备(如:硬盘、网卡等)都需要和 CPU 有某种形式的通信以便 CPU 及时知道发生了什么事情,这样 CPU 可能就会放下手中的事情去处理应急事件,硬件设备主动打扰 CPU 的现象就可称为硬件中断
每个硬件设备都中断,那么如何区分不同硬件呢?不同设备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?
系统上的每个硬件设备都会被分配一个 IRQ 号,通过这个唯一的 IRQ 号就能区别
在计算机里,中断是一种电信号,由硬件产生,并直接送到中断控制器(如 8259A)上,然后再由中断控制器向 CPU 发送信号,CPU 检测到该信号后,就中断当前的工作转而去处理中断。然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。现在来看一下中断控制器,常见的中断控制器有两种:可编程中断控制器 8259A 和高级可编程中断控制器(APIC),中断控制器应该在大学的硬件接口和计算机体系结构的相关课程中都学过。传统的 8259A 只适合单 CPU 的情况,现在都是多 CPU 多核的 SMP 体系,所以为了充分利用 SMP 体系结构、把中断传递给系统上的每个 CPU 以便更好实现并行和提高性能,Intel 引入了高级可编程中断控制器(APIC)。
光有高级可编程中断控制器的硬件支持还不够,Linux 内核还必须能利用到这些硬件特质,所以只有 kernel 2.4 以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为 SMP IRQ Affinity.
========================================================
个人遇到的问题,LVS服务器(高流量 Web 服务器)
单核cpu使用满载,导致业务告警,可以看出其他核很空闲,关闭systemctl stop irqbalance,手动配置多CPU下网卡中断分配调优
查看流量网卡,这里是band两张网卡(enp70s0f0、enp70s0f1)
查看网卡支持的多队列数:
从/proc/interrupts里查到网卡中断号(IRQ号码),设备一般都有自己的IRQ号码(当然一个设备还有可能有多个IRQ号码)
cat /proc/interrupts | awk \'{print $1, $NF}\' | grep \'enp70s0f1\'
查看这些中断号都是哪些cpu核在处理
for x in {182..244};do cat /proc/irq/$x/smp_affinity_list;echo "=====$x===";done
for x in {95..161};do cat /proc/irq/$x/smp_affinity_list;echo "=====$x===";done
通过分析可以看出有多数中断号是cpu14核在处理,这也是为什么cpu14 的si软中断为100%
优化:
1.关闭自带的irqbalance服务, 默认情况下,有一个irqbalance在对IRQ进行负载均衡
systemctl status irqbalance
systemctl stop irqbalance
2.查看机器cpu情况
3.重新分配内核处理网卡的中断号,怎么分不强求,分好观察测试
echo "10" > /proc/irq/182/smp_affinity_list
echo "11" > /proc/irq/183/smp_affinity_list
echo "12" > /proc/irq/184/smp_affinity_list
echo "13" > /proc/irq/185/smp_affinity_list
echo "14" > /proc/irq/186/smp_affinity_list
echo "15" > /proc/irq/187/smp_affinity_list
echo "16" > /proc/irq/188/smp_affinity_list
echo "17" > /proc/irq/189/smp_affinity_list
echo "18" > /proc/irq/190/smp_affinity_list
echo "19" > /proc/irq/191/smp_affinity_list
........
........
echo "62" > /proc/irq/234/smp_affinity_list
echo "63" > /proc/irq/235/smp_affinity_list
echo "1" > /proc/irq/236/smp_affinity_list
echo "2" > /proc/irq/237/smp_affinity_list
echo "3" > /proc/irq/238/smp_affinity_list
echo "4" > /proc/irq/239/smp_affinity_list
echo "5" > /proc/irq/240/smp_affinity_list
echo "6" > /proc/irq/241/smp_affinity_list
echo "7" > /proc/irq/242/smp_affinity_list
echo "8" > /proc/irq/243/smp_affinity_list
echo "9" > /proc/irq/244/smp_affinity_list
4.top观察生效,解决问题
===================后续通过监控继续观察========(添加监控)============
1.创建监控模板(Automatically discover cpu-core)
2.创建应用集(CPU-CORE-item)
3.创建自动发现规则 (Automatically discover cpu-core)键值:system.cpu.discovery
4.创建监控项原型 (cpucore-softirq{#CPU.NUMBER})
5.创建图形原型 (cpucore-softirq)
6.创建触发器类型
7.绑定模板聚合图像
具体绑定机器--》图形---》创建
8.查看
9.其他单核监控值根据需要添加
system.cpu.util[,softirq]
system.cpu.util[,iowait]
system.cpu.util[,idle]
system.cpu.util[,system]
system.cpu.util[,steal]
system.cpu.util[,nice]
system.cpu.util[,interrupt]