RPS 与 RFS 是什么
RPS(Receive Packet Steering)用软件方式把收包处理分散到多个 CPU,适用于单队列网卡与虚拟网卡;RFS(Receive Flow Steering)在其之上记录流与 CPU 的对应关系,让处理同一条流的应用线程与收包处理尽量落在同一核上,减少跨核缓存失效。二者都作用于收包路径,是缺少硬件多队列时的补强手段。
基本信息
| rps_cpus | 每个接收队列的 CPU 位图,十六进制表示 |
|---|---|
| rps_flow_cnt | 该队列的流表条目数 |
| rps_sock_flow_entries | 全局 socket 流表条目数,位于 /proc/sys/net/core/ |
| 配置路径 | /sys/class/net/<dev>/queues/rx-*/ |
| 适用前提 | 单队列网卡或虚拟网卡,软中断集中在少数核上 |
典型使用场景
- 虚拟网卡只有单队列,软中断把单个 CPU 打满
- 容器网络收包集中在少数核,业务线程排队等 CPU
- 测试环境网卡不支持多队列,却要模拟高并发收包
- 与中断亲和配合,把收包与业务线程放在同一 NUMA 节点
- CPU 拓扑不均衡时手工引导流量,避免个别核长期饱和
启用 RPS
启用 RPS
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries # 全局流表条目
echo ffff > /sys/class/net/eth0/queues/rx-0/rps_cpus # 启用 CPU0-15
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt # 该队列的流表条目
cat /proc/softirqs | head -5 # 观察软中断分布是否变均衡参数作用
| 参数 | 作用 | 注意 |
|---|---|---|
| rps_cpus | 指定哪些 CPU 参与该队列的收包处理 | 十六进制位图,写错会集中到单核 |
| rps_flow_cnt | 每队列可跟踪的流数量 | 过小会导致回退到无流信息的分发 |
| rps_sock_flow_entries | 全局流表规模 | 需大于各队列 rps_flow_cnt 之和 |
rps_cpus 是十六进制位图:1 表示仅 CPU0,4 表示仅 CPU2,ffff 表示 CPU0 到 CPU15。写错掩码会让流量集中到一个核,效果与调优目标相反。
RFS 的收益依赖流表:只开 RPS 而不配置 rps_sock_flow_entries 与 rps_flow_cnt,收包会在核间迁移并带来额外的缓存失效开销。
验证与回退
- 启用后对比 /proc/softirqs 中各 CPU 的 NET_RX 增量是否趋于均衡
- 压测对比启用前后的收包吞吐与 CPU 使用率,确认收益确实存在
- 收益不明显或延迟变差时,把 0 写回 rps_cpus 即可关闭
- 关闭后确认软中断分布回到原状,避免只改了部分队列
- 配置需写入开机脚本或 udev 规则,否则重启后失效