本文针对高并发服务的入出站流量,给出从硬件队列到内核网络栈的可验证优化路径,确保跨节点访问最小化与中断抖动收敛。
## 前提与识别
查看 CPU/NUMA 拓扑与网卡队列:
lscpu | egrep 'Socket|NUMA|CPU\(s\)'
numactl --hardware
ethtool -l eth0 # 查看队列配置(RX/TX)
ethtool -S eth0 | head # 部分驱动统计(丢包/队列计数)
## IRQ 绑定(中断亲和性)
目标:将网卡中断分配到靠近对应 NUMA 节点的 CPU,减少远端访问。
步骤:
# 1. 找到网卡相关 IRQ
grep eth0 /proc/interrupts
# 2. 为每个 IRQ 设置 CPU 掩码(示例绑定到节点0的 CPU)
echo 0x000000FF | sudo tee /proc/irq/123/smp_affinity
echo 0x000000FF | sudo tee /proc/irq/124/smp_affinity
说明:掩码需按实际 CPU 数与节点映射计算;如启用 `irqbalance`,需配置其规则避免覆盖手动绑定。
验证:重复 `grep eth0 /proc/interrupts`,观察计数是否集中到目标 CPU。
## RPS/RFS(接收端软中断与流量分配)
RPS(Receive Packet Steering):将软中断在多个 CPU 间分配;RFS(Receive Flow Steering):依据流关联将报文分配到处理该流的 CPU。
启用与配置:
# 为所有 RX 队列启用 RPS,掩码绑定到目标节点 CPU
for q in /sys/class/net/eth0/queues/rx-*/rps_cpus; do echo 0x000000FF | sudo tee $q; done
# 配置 RFS 的全局流条目
echo 32768 | sudo tee /proc/sys/net/core/rps_sock_flow_entries
for q in /sys/class/net/eth0/queues/rx-*/rps_flow_cnt; do echo 4096 | sudo tee $q; done
验证:
- 通过 `ethtool -S eth0` 查看队列收包分布是否更均衡。
- 结合应用层线程亲和性,观察 `sirq`(软中断)占比与 p95/p99 延迟变化。
## 发送队列与亲和性
# 查看与调整 TX 队列
ethtool -l eth0
sudo ethtool -L eth0 rx 8 tx 8 # 示例,将队列数设置为 8
结合应用线程与队列映射,减少跨节点发送。部分驱动支持 XPS(Transmit Packet Steering),可按 CPU 掩码设置到对应 TX 队列。
## 回归与观察指标
- `sar -n DEV 1 60`:观察吞吐与丢包。
- `mpstat -P ALL 1 60`:观察软中断与 CPU 利用率变化。
- 应用层:记录接口 p95/p99、队列长度与超时率,确认优化收益。
## 注意事项
- 中断/队列亲和性需与 NUMA 线程绑定策略协同;避免把工作线程绑在远端节点导致收益抵消。
- 不同驱动的统计项差异较大,必要时查阅驱动文档(`ethtool --show-nfc` 等)。
- `irqbalance` 在部分场景会打散亲和性,需按需禁用或自定义规则。
## 结语
通过 IRQ 绑定与 RPS/RFS 的联合优化,并以明确的回归指标验证效果,可以将网络栈的“不可预测抖动”转变为“可控的亲和性策略”。这在多路服务器与高并发服务中尤为关键。

发表评论 取消回复