3. 网卡多队列技术:RSS 原理与队列-CPU 映射
RSS(Receive Side Scaling,接收端缩放)是网卡多队列技术的核心机制。它允许网卡将接收到的网络数据流分散到多个硬件队列中,再由多个 CPU 核心并行处理,从而突破单 CPU 瓶颈,提升整体网络吞吐量。本章深入解析 RSS 的哈希分发原理、队列与 CPU 的映射关系,以及关键配置参数。
3.1 RSS 核心原理:哈希分发
RSS 的核心思想是:网卡硬件根据数据包头部字段计算哈希值,然后通过哈希值选择对应的接收队列。同一数据流(如 TCP 连接)的所有数据包会被哈希到同一个队列,保证数据包的有序性;不同流则可能被分发到不同队列,实现并行处理。
关键哈希字段(默认):
- IPv4 TCP/UDP:源 IP + 目的 IP + 源端口 + 目的端口(四元组)
- IPv6 TCP/UDP:源 IP + 目的 IP + 源端口 + 目的端口
- 非分片 IPv4:源 IP + 目的 IP(二元组)
实践要点:RSS 哈希仅基于 L3/L4 头部,不涉及 payload。加密隧道(如 IPsec)可能导致哈希分布不均匀,需根据实际场景调整哈希字段。
3.2 队列与 CPU 的映射关系
RSS 将数据包分发到硬件队列后,还需要将队列绑定到具体的 CPU 核心。这个映射关系通过 indirection table(重定向表) 和 CPU mask(CPU 掩码) 共同控制。
3.2.1 Indirection Table(重定向表)
Indirection table 是一个数组,每个表项存储一个队列索引。哈希值对表项数量取模后,得到表项索引,进而确定目标队列。表项数量通常为 128 或 512,可动态调整。
映射公式:
Queue_Index = Indirection_Table[ Hash_Value % Table_Size ]
3.2.2 CPU Mask(CPU 掩码)
每个队列可以关联一个 CPU 掩码,指定该队列的中断可以发送到哪些 CPU 核心。实际中断分配由中断控制器(如 MSI-X)根据掩码和负载情况决定。
| 组件 | 作用 | 配置接口 |
|---|---|---|
| Indirection Table | 哈希值 → 队列索引的映射表 | ethtool -x / ethtool -X |
| CPU Mask | 队列中断允许的 CPU 集合 | /proc/irq/<IRQ>/smp_affinity |
| 队列数 | 网卡支持的硬件队列数量 | ethtool -l / ethtool -L |
常见误区:修改 indirection table 只影响数据包到队列的映射,不影响中断到 CPU 的映射。中断绑定需单独设置
smp_affinity。两者配合才能实现完整的 RSS 优化。
3.3 关键配置参数与查看方法
以下命令用于查看和修改 RSS 相关配置,是日常性能调优的基础工具。
3.3.1 查看当前队列数
# 查看网卡支持的最大队列数和当前队列数
ethtool -l eth0
# 输出示例
Channel parameters for eth0:
Pre-set maximums:
RX: 0
TX: 0
Other: 0
Combined: 8
Current hardware settings:
RX: 0
TX: 0
Other: 0
Combined: 4
3.3.2 查看 Indirection Table
# 查看当前 indirection table 内容
ethtool -x eth0
# 输出示例(简化)
RX flow hash indirection table for eth0 with 4 RX queue(s):
0: 0 1 2 3 0 1 2 3
8: 0 1 2 3 0 1 2 3
16: 0 1 2 3 0 1 2 3
...(共 128 个表项)
3.3.3 查看哈希字段
# 查看当前 RSS 哈希字段配置
ethtool -n eth0 rx-flow-hash tcp4
# 输出示例
TCP over IPV4 flows use these fields:
Source IP address
Destination IP address
Source port
Destination port
3.3.4 查看中断与 CPU 绑定
# 查看网卡中断号及当前 CPU 亲和性
cat /proc/interrupts | grep eth0
# 输出示例
CPU0 CPU1 CPU2 CPU3
123: 12345 0 0 0 IR-PCI-MSI eth0-TxRx-0
124: 0 23456 0 0 IR-PCI-MSI eth0-TxRx-1
125: 0 0 34567 0 IR-PCI-MSI eth0-TxRx-2
126: 0 0 0 45678 IR-PCI-MSI eth0-TxRx-3
3.4 映射策略对比
| 策略 | 描述 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 1:1 映射 | 每个队列绑定到唯一 CPU | 高吞吐、低延迟场景 | 无竞争,缓存友好 | 队列数受限于 CPU 数 |
| N:1 映射 | 多个队列绑定到同一 CPU | CPU 核心数少于队列数 | 充分利用多队列硬件 | 单 CPU 可能成为瓶颈 |
| 1:N 映射 | 一个队列中断可发送到多个 CPU | 负载均衡、故障转移 | 提高中断处理灵活性 | 可能引入缓存抖动 |
| NUMA 感知映射 | 队列绑定到同 NUMA 节点的 CPU | 多 NUMA 节点服务器 | 避免跨 NUMA 访问延迟 | 配置复杂度高 |
推荐实践:在大多数场景下,采用 1:1 映射(队列数 = CPU 核心数)并配合 NUMA 感知绑定,可以获得最佳性能。对于超线程环境,建议将队列绑定到物理核心而非逻辑核心。
3.5 常见问题与排查
- 哈希不均匀:使用
ethtool -S eth0 | grep rx_queue查看各队列收包计数,若偏差超过 20%,考虑调整 indirection table 或哈希字段。 - 中断集中在单 CPU:检查
/proc/irq/<IRQ>/smp_affinity是否设置为多 CPU 掩码,或检查 BIOS 中中断分发设置。 - 队列数无法修改:部分网卡驱动要求先
ifconfig eth0 down才能修改队列数。 - 虚拟化环境:虚拟机内 RSS 可能被宿主机限制,需确认 virtio 或 SR-IOV 的队列支持情况。