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)可能导致哈希分布不均匀,需根据实际场景调整哈希字段。
RSS 哈希分发流程 网络数据包 (IP + Port 四元组) Toeplitz 哈希 (硬件计算) Hash 值 (32-bit) 取模映射 (Hash % N) Queue 0 Queue 1 Queue 2 Queue 3 说明: 同一 TCP 连接的四元组相同 → 哈希值相同 → 始终进入同一队列 → 保证数据包有序。 不同连接的四元组不同 → 哈希值不同 → 可能进入不同队列 → 实现多核并行。

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 优化。
队列与 CPU 映射架构 网卡硬件 (NIC) Queue 0 Queue 1 Queue 2 Queue 3 Queue 4 MSI-X 中断控制器 (中断路由) CPU 0 CPU 1 CPU 2 CPU 3 CPU 4 Indirection Table 控制数据包 → 队列映射;smp_affinity 控制队列中断 → CPU 映射。两者独立配置。

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 的队列支持情况。