网卡多队列(RSS)与软中断(RPS/RFS)性能调优
发布时间:2026/9/7 18:04:12 作者:尧图编辑部 阅读量:1,286
与软中断(RPS/RFS)性能调优)
网卡多队列RSS与软中断RPS/RFS性能调优在万兆10Gbps乃至 100Gbps 高速网络普及的今天许多运维工程师在管理 Kubernetes 高并发网络网关或数据库数据节点时经常会遇到一种诡异的“局部性能崩溃”现象登录服务器执行top命令整机的平均 CPU 利用率明明只有 8%看起来非常空闲但仔细观察每个 CPU 核心的细分指标会震惊地发现CPU 0 核心的软中断利用率%si, Software Interrupt持续处于 100% 爆满状态内核守护进程ksoftirqd/0牢牢霸占单核算力而与之相邻的 CPU 1 到 CPU 31 核心的%si却全部是 0.0%。在这一时刻尽管整机还有 31 个核心完全闲置但所有经过该节点的数据包已经开始大面积发生延迟陡增、缓冲区溢出Overrun与静默丢包。这种“单核被打死、三十核围观”的现象根源在于 Linux 内核网络协议栈的软中断单核绑定缺陷。要彻底释放多核服务器的网络吞吐潜力必须深入理解并配置硬件网卡多队列RSS与 Linux 内核软中断分发RPS/RFS体系。为什么软中断会集中压死单核在传统的单队列网卡或未经调优的虚拟化环境中网卡收到外部网络数据包后会向 CPU 发送一个硬件中断Hard IRQ。CPU 响应硬件中断后触发内核的软中断Soft IRQ即 NET_RX 处理函数从网卡的 DMA 环形缓冲区Ring Buffer中读取数据包并向上层 TCP/IP 协议栈传递。如果网卡只有一个接收队列或者所有硬件中断都被操作系统默认绑定到了同一个 CPU 核心通常是 CPU 0上那么整台物理机上所有的网络数据包解包、校验和计算、路由与 iptables 过滤全部被死死压在 CPU 0 这单单一颗核心上。当每秒网络数据包数量PPS突破 30 万时单颗 CPU 核心的算力就会被软中断彻底耗尽新的数据包在网卡 Ring Buffer 中因排队溢出被直接丢弃。[ 未调优: 单队列单核瓶颈 (CPU 0 软中断 100% 爆满丢包严重) ] 网卡数据流 ──► [ 单硬件中断队列 ] ──► [ CPU 0 独抗全部 SoftIRQ ] (CPU 1~31 全部闲置) [ 调优后: RSS 硬件多队列 RPS 多核分发 (负载绝对均匀) ] 网卡数据流 ──► [ 硬件队列 0 ] ──► CPU 0 ──► [ 硬件队列 1 ] ──► CPU 1 ──► [ 硬件队列 2 ] ──► CPU 2 ──► [ 硬件队列 3 ] ──► CPU 3解决方案一硬件网卡多队列RSS, Receive Side Scaling现代企业级网卡如 Intel、Mellanox 或云厂商的高级网卡支持在硬件层面维护多个独立的收发收包队列多达 8 到 64 个。网卡内部通过硬件 ASIC 芯片根据数据包的四元组源IP、目的IP、源端口、目的端口计算 Toeplitz 哈希将不同的 TCP 连接均匀分发到不同的硬件接收队列中。1. 查看与配置网卡硬件队列数# 查看网卡 eth0 支持的最大队列数与当前生效队列数 ethtool -l eth0 # 若当前队列未开满调大网卡通道队列数至 8 (与 CPU 核心数匹配) ethtool -L eth0 combined 82. 启用系统中断均衡守护进程irqbalance确保系统服务irqbalance正常运行或者手动将各个网卡队列的中断亲和性SMP Affinity均匀绑定到不同的 CPU 核心上# 查看网卡中断分配 cat /proc/interrupts | grep eth0 # 启动并配置 irqbalance systemctl enable --now irqbalance解决方案二内核软件分发补丁——RPS 与 RFS在很多公有云虚拟机或部分不支持硬件多队列的廉价网卡上硬件中断依然只能投递给单核。此时必须开启 Linux 内核提供的纯软件多核负载均衡机制RPSReceive Packet Steering与RFSReceive Flow Steering。RPS软件多队列分发单队列网卡收到数据包并触发硬件中断后CPU 在驱动层计算数据包哈希并通过软件中断将数据包投递给其他空闲 CPU 核心的backlog队列进行协议栈解析。RFS应用感知流分发进一步追踪当前正在处理该套接字的应用进程如 Nginx Worker运行在哪个 CPU 核心上将数据包直接投递给应用所在的同一个 CPU 处理极大提升 CPU L1/L2 缓存命中率Cache Locality。自动化开启 RPS/RFS 生产脚本编写并在系统启动时执行以下脚本#!/bin/bash # 自动为网卡所有接收队列开启 RPS将软中断均衡分发到全量 CPU 核心 # 1. 计算当前系统全量 CPU 的十六进制掩码 (例如 32 核对应 ffffffff) CPUS$(nproc) MASK$(printf %x $(( (1 CPUS) - 1 ))) # 2. 遍历网卡所有 rx 队列并注入 CPU 掩码 for rps_file in /sys/class/net/eth0/queues/rx-*/rps_cpus; do echo $MASK $rps_file done # 3. 调大全局软中断积压队列上限 (防止突发瞬时丢包) sysctl -w net.core.netdev_max_backlog65535 # 4. 开启 RFS 全局流表与单队列流表 echo 65536 /proc/sys/net/core/rps_sock_flow_entries for rfs_file in /sys/class/net/eth0/queues/rx-*/rps_flow_cnt; do echo 4096 $rfs_file done echo [SUCCESS] 网卡 RPS/RFS 多核软中断调优已生效CPU 掩码: $MASK调优成效与性能复盘在完成网卡硬件多队列绑定与 RPS/RFS 软中断多核均衡后我们在 80 万 PPS数据包/秒的网关极限压测中进行了效果比对CPU 软中断分布原本 CPU 0 单核 100% 锁死的现象彻底消失软中断被完美均摊在 32 颗物理核心上单核%si稳定在3%~5%的极低水位。网络转发延迟P99从原本丢包状态下的 180ms 锐减至0.8ms。整机网络吞吐上限从原本受限于单核的 35 万 PPS 直接飙升突破120 万 PPS彻底清除了高速网络环境下的单核软中断瓶颈。