irqbalance是Linux下一个容易被忽视却十分关键的守护进程。它的核心任务是把硬件中断(IRQ)合理地分发到各个CPU核心上处理,避免中断处理压力全部压在一个核心上。在高并发的网络服务器、数据库服务器场景中,中断分配是否合理,往往直接决定了系统能否充分利用多核性能。本文将从原理入手,介绍irqbalance的工作机制,并给出具体的配置与调优方法。

一、理解中断与中断分配不均的问题
硬件设备在需要CPU处理数据时,会向CPU发送中断请求。比如网卡收到数据包、磁盘完成一次IO、定时器到期,都会触发中断。CPU收到中断后,会暂停当前任务,转而执行中断处理程序。中断处理本身是有开销的,如果大量中断都涌向同一个核心,这个核心就会忙于响应中断,用户态任务得不到执行时间,表现为si(软中断)指标居高不下。
在没有做任何干预的情况下,很多设备的硬中断默认由CPU 0处理。这是因为Linux系统启动时,所有中断的亲和性掩码默认都指向第一个核心。在单核时代这不是问题,但现代服务器动辄几十个核心,如果一个万兆网卡每秒数十万次中断全部交给CPU 0,就会出现典型的性能瓶颈:top命令中CPU 0的%si接近100%,而其他核心几乎闲置。此时网络吞吐量上不去,应用层处理能力也跟着受限。
软中断的处理同样值得关注。硬中断处理程序只做最小化的工作,把耗时的处理推迟到软中断(如NET_RX_SOFTIRQ)中完成。软中断会在触发它的那个CPU上执行,因此硬中断分配在哪里,软中断的压力就落在哪里。这就是为什么优化中断分配时,既要看/proc/interrupts`中硬中断的计数,也要看/proc/softirqs的分布情况。
二、irqbalance的工作机制
irqbalance通过周期性地扫描系统中所有中断的分布情况,结合各个CPU核心的负载状态,重新计算中断亲和性,把中断迁移到更合适的核心上。它引入了几个关键概念:首先是CPU层级树,把物理CPU、Cache域、核心逐级组织成树形结构;其次是中断分类,不同类型的中断被标记不同的权重,比如网卡中断属于高权重类别,而定时器中断权重较低。
默认情况下,irqbalance每隔10秒做一次平衡决策。它会尽量避免频繁迁移中断,因为迁移本身会带来Cache失效的代价。对于支持多队列的网卡(如Intel 82599、Mellanox系列),irqbalance会把不同的队列中断分散到不同的核心上,这正好利用了现代网卡的RSS(接收端扩展)特性,让多个核心并行处理网络流量。
查看irqbalance是否在运行很简单:
systemctl status irqbalance ps -ef | grep irqbalance
需要注意一点:irqbalance适合大多数通用场景,但在某些低延迟或高吞吐的专项场景中,它的自动决策可能反而不如手动绑定。比如NFV、高频交易等环境,运维人员往往关闭irqbalance,改为固定中断亲和性,以获得确定性的延迟表现。
三、手动配置中断亲和性
如果不使用irqbalance,或者想覆盖它的决策,可以直接通过/proc/irq/<irq号>/smp_affinity文件设置中断亲和性。这个文件的内容是一个十六进制位掩码,每一位对应一个CPU核心。例如系统有8个核心,把中断绑定到CPU 2上,掩码的二进制是00000100,写成十六进制就是04:
# 查看网卡中断号 cat /proc/interrupts | grep eth0 # 把中断号为42的设备绑定到CPU 2 echo 04 > /proc/irq/42/smp_affinity
对于超过32个核心的系统,掩码会分为多个32位组,用逗号分隔,比如00000001,00000000表示CPU 32。手写掩码容易出错,可以借助taskset辅助计算:
# 生成绑定到CPU 2的掩码 taskset -c 2 cat /proc/self/status | grep Cpus_allowed_list
手动绑定的典型做法是:把网卡队列中断均匀分配到NUMA本地节点的一组核心上,同时避开CPU 0(因为CPU 0还要处理定时器等系统默认中断)。对于多队列网卡,可以编写脚本自动完成分配:
#!/bin/bash
# 把eth0各队列中断轮流绑定到核心2到7
irqs=$(grep eth0 /proc/interrupts | awk -F: '{print $1}')
cpu=2
for irq in $irqs; do
mask=$(printf "%x" $((1 << cpu)))
echo $mask > /proc/irq/$irq/smp_affinity
echo "IRQ $irq -> CPU $cpu"
cpu=$(( (cpu + 1) % 8 ))
[ $cpu -lt 2 ] && cpu=2
done绑定完成后,持续观察/proc/interrupts中各中断的计数增长情况,确认流量确实分散到了预期的核心上。
四、irqbalance的配置调优与效果验证
irqbalance的主配置文件是/etc/irqbalance/irqbalance.env(旧版本为/etc/sysconfig/irqbalance)。可以调整的参数包括平衡周期、日志级别、以及是否启用banned列表。banned列表允许指定某些中断或某些CPU不参与自动平衡,这在手动管理关键设备中断时非常有用:
# 环境变量方式配置 IRQBALANCE_BANNED_CPULIST=0,1 IRQBALANCE_INTERVAL=5
上面配置把CPU 0和1排除在平衡范围外,并把平衡周期缩短为5秒。另外还可以通过/etc/irqbalance/policyscript定义自定义策略脚本,对特定设备的中断类型做特殊处理,比如把存储设备中断固定到某个NUMA节点。
验证优化效果需要对比调优前后的指标。常用的观察命令包括:
# 每2秒刷新一次各核心中断计数 watch -d -n 2 "cat /proc/interrupts | grep eth0" # 观察软中断在各CPU上的分布 cat /proc/softirqs # 结合mpstat查看每核心的软中断占比 mpstat -P ALL 2 5
理想的优化结果是:万兆网卡满载时,各处理核心的%soft基本均衡,没有单核打满的情况;应用层吞吐量有可测量的提升;在NUMA架构上,中断处理核心与网卡所在的NUMA节点一致,跨节点访问内存的延迟降到最低。
最后补充一个实践中容易踩的坑:如果开启了网卡的多队列但队列数少于核心数,中断仍会集中。这时需要结合ethtool调整队列数量,让队列数与参与处理的核心数匹配。irqbalance、多队列网卡、RSS三者配合好,多核系统的中断处理能力才能真正释放出来。
irqbalanceCPU中断分配中断亲和性修改时间:2026-09-12 09:14:33