关键不是让中断变快,而是将网卡IRQ与关键应用分隔并固定到可预测物理核,避免缓存污染、TLB刷新和NUMA跨节点访问;需先用/proc/interrupts和mpstat识别热点,再通过smp_affinity_list绑定、禁用irqbalance,并配套隔离应用进程。

绑定特定 CPU 核心减少网络中断处理的上下文开销,关键不是“让中断变快”,而是把高频、低延迟敏感的中断(比如网卡收包 IRQ)和关键应用进程分隔开,并固定到物理位置可预测的核心上,从而避免缓存污染、TLB 刷新和 NUMA 跨节点访问——这些才是抖动和延迟飙升的真正源头。
先识别真正的中断热点
别凭感觉配,先看数据:
- 运行 cat /proc/interrupts,重点关注以 eth0-TxRx-、mlx5_0- 或 enp3s0f1: 开头的行,观察各 CPU 列数字是否严重不均(比如 CPU0 累计 200 万次,CPU3 才 5 万)
- 用 mpstat -P ALL 1 持续观察,确认高软中断(%soft)是否集中在某几个核上
- 结合 lscpu 查清物理核数、超线程开关状态及 NUMA 节点分布,避免把中断绑到超线程兄弟核或远端内存节点
精准设置中断亲和性
中断绑定靠写 /proc/irq/*/smp_affinity 或 smp_affinity_list,推荐后者(更易读):
- 查目标网卡 IRQ 号:运行 grep eth0 /proc/interrupts | awk '{print $1}' | tr -d ':'
- 假设 IRQ 123 对应主收包队列,想绑定到 CPU2 和 CPU3:执行 echo 2-3 > /proc/irq/123/smp_affinity_list
- 若需严格限定在单个物理核(如 CPU4),且该核无超线程干扰:用 echo 4 > /proc/irq/123/smp_affinity_list
- 务必禁用 irqbalance 服务:systemctl stop irqbalance && systemctl disable irqbalance,否则它会覆盖手动配置
配套隔离关键应用进程
光绑中断不够,还得防止 nginx、Redis 或用户态 DPDK 程序被挤到同一核上抢资源:
- 为 nginx worker 显式设 worker_processes 4; + worker_cpu_affinity 0001 0010 0100 1000;(对应 CPU0–3)
- 启动 Redis 时用 taskset -c 8-11 redis-server /etc/redis.conf,避开中断绑定核(0–3)和系统保留核(如 0)
- 若用 systemd,加 CPUAffinity=8 9 10 11 到 service 文件中,并确保 CPUSchedulingPolicy=other
- 检查是否生效:ps -eo pid,args,psr | grep redis 看第三列是否落在预期范围;再用 taskset -cp
确认实际掩码
验证效果与常见陷阱
配置完必须实测,否则等于没调:
- 压测时运行 mpstat -P ALL 1,确认中断绑定核的 %soft 占比显著上升,而其他核负载回落
- 用 perf stat -e cycles,instructions,cache-misses -p
对比绑核前后 L2 缓存缺失率,下降 10%+ 表明局部性改善 - 警惕陷阱:绑定核上有定时器迁移(检查 /proc/sys/kernel/timer_migration 是否为 1)、有 ksoftirqd 占满 CPU、或 cgroup 限额导致调度失真
- 虚拟机环境慎用硬绑定,优先配合 vCPU pinning 和 host 侧 irq 分配,避免宿主机调度扰动放大抖动

















