网络基础设施调优:RoCE v2 配置、PFC/ECN 流控、MTU 巨帧设置、网卡多队列(RSS)绑定

各位好,咱们接着聊NVMe over Fabrics的性能优化。上一章我们把目光聚焦在CPU和内存上,这一章,我们把视线拉到网卡和交换机上。

说白了,NVMe over Fabrics跑的是存储协议,对网络的延迟和吞吐要求极高。你想想看,一个NVMe命令的延迟,如果网络部分占了50微秒,那整个IO路径就废了。所以,网络基础设施的调优,是绕不开的一环。

我个人习惯,先把网络调优分成四个维度:协议卸载(RoCE v2)、流控机制(PFC/ECN)、报文大小(MTU)、以及并行处理(RSS)。这四个点,任何一个没调好,性能都会大打折扣。

网络基础设施调优核心逻辑 NVMe over Fabrics RoCE v2 配置 PFC / ECN 流控 MTU 巨帧设置 网卡多队列 (RSS) 绑定 四个维度相互影响,缺一不可 RoCE v2 是基础,PFC/ECN 保无损,MTU 提效率,RSS 扩并行

1. RoCE v2 配置:RDMA 的基石

RoCE v2,全称是RDMA over Converged Ethernet version 2。说白了,就是把RDMA的报文封装在UDP里,跑在标准以太网上。相比RoCE v1只能在同一个二层网络里跑,v2可以跨三层路由,灵活多了。

配置RoCE v2,核心就两步:网卡支持和驱动加载。

首先,你得确认网卡支持RoCE。Mellanox(现在叫NVIDIA)的ConnectX系列、Broadcom的NetXtreme系列,基本都支持。我建议你用ibstat或者rdma link show看一眼。

# 查看RDMA设备状态
rdma link show
# 输出示例:
# link mlx5_0/1 state ACTIVE physical_state LINK_UP netdev ens3f0np0

# 确认RoCE模式
cma_roce_mode -d mlx5_0
# 如果返回 2,表示 RoCE v2

嗯,这里要注意。有些网卡默认是RoCE v1,你得手动切到v2。怎么切?用cma_roce_mode工具就行。

# 切换到 RoCE v2
cma_roce_mode -d mlx5_0 -m 2

我在项目中遇到过一个问题:RoCE v2配好了,但两台机器就是ping不通RDMA。查了半天,发现是交换机的UDP端口没放行。RoCE v2默认用UDP端口4791,别忘了在交换机上配ACL放行这个端口。

⚠️ 避坑指南: 我曾经在某个数据中心部署时,RoCE v2死活起不来。最后发现是交换机的PFC配置和网卡不匹配。记住,RoCE v2依赖无损网络,PFC必须配好。否则,丢包率一高,性能直接崩。

2. PFC/ECN 流控:保无损,降延迟

RoCE v2跑在以太网上,以太网本身是会丢包的。但RDMA协议要求无损传输,怎么办?靠流控。

流控有两个层次:链路层的PFC(Priority Flow Control)和网络层的ECN(Explicit Congestion Notification)。

PFC,说白了就是交换机告诉网卡:「兄弟,你慢点发,我这边队列满了。」它基于802.1Qbb标准,按优先级做流控。配置PFC,需要网卡和交换机两端都打开。

# 在Mellanox网卡上启用PFC(优先级3)
mlxreg -d /dev/mst/mt4123_pciconf0 --reg_name PPCC --set "prio=3,an_disable=1"

# 查看PFC统计
ethtool --show-pfc ens3f0np0

ECN呢,更高级一点。它不直接让发送方停,而是在IP头里打一个标记,告诉接收方:「网络有点堵了,你让发送方降速吧。」接收方收到ECN标记后,通过CNP(Congestion Notification Packet)通知发送方,发送方就主动降速。

我个人习惯,PFC和ECN一起用。PFC做最后一公里的保底,ECN做全局的拥塞控制。只开PFC不开ECN,容易导致PFC风暴——一个队列堵了,整个链路都停摆。

💡 调优建议: ECN的阈值设置很关键。阈值设得太低,频繁触发降速,吞吐上不去;设得太高,拥塞了也不通知,丢包就来了。我一般从Kmin=50000、Kmax=150000开始调,然后根据实际流量微调。
# 在交换机上配置ECN(以Cisco Nexus为例)
interface ethernet 1/1
  priority-flow-control mode on
  priority-flow-control priority 3
  ecn
  ecn threshold 50000 150000

3. MTU 巨帧设置:大包更高效

MTU,最大传输单元。标准以太网MTU是1500字节。但对于NVMe over Fabrics,我强烈建议你用巨帧(Jumbo Frame),MTU设到9000字节。

为什么?你想想看,NVMe的IO大小通常是4KB、8KB甚至更大。如果MTU只有1500,一个IO请求要拆成好几个包,CPU要处理更多的中断,网卡要处理更多的分段重组。说白了,效率低。

用9000字节的MTU,一个包就能装下大部分NVMe命令和数据,CPU开销直接降一半。

# 设置MTU为9000
ip link set dev ens3f0np0 mtu 9000

# 确认MTU
ip link show ens3f0np0 | grep mtu

嗯,这里有个坑。MTU必须端到端一致——网卡、交换机、对端网卡,都得设成9000。我曾经遇到一个案例,网卡设了9000,但交换机某个端口忘了改,结果大包被交换机丢弃,性能反而比1500还差。

🔧 小技巧: 用ping -M do -s 8972测试MTU连通性。8972是9000减去IP头和ICMP头的长度。如果ping通了,说明MTU 9000端到端可用。

4. 网卡多队列(RSS)绑定:让每个CPU都忙起来

RSS,Receive Side Scaling。说白了,就是让网卡把收到的包分散到多个CPU核心上处理,而不是让一个核心累死,其他核心闲着。

NVMe over Fabrics是高并发场景,一个队列一个CPU核心,是最理想的。我建议你把RSS队列数设为和CPU核心数一样多,然后把每个队列绑定到不同的核心上。

# 查看当前RSS队列数
ethtool -l ens3f0np0
# 输出示例:
# Combined: 8
# 如果不够,可以增加
ethtool -L ens3f0np0 combined 16

# 查看当前RSS哈希配置
ethtool -x ens3f0np0

RSS的哈希策略也很重要。默认情况下,网卡根据IP和端口做哈希。但对于NVMe over Fabrics,我建议你把源IP、目的IP、源端口、目的端口都纳入哈希计算,这样每个TCP连接都能均匀分布到不同核心上。

# 设置RSS哈希字段(以Mellanox为例)
ethtool -N ens3f0np0 rx-flow-hash tcp4 sdfn
# s = 源IP, d = 目的IP, f = 源端口, n = 目的端口

绑定队列到核心,可以用irqbalance或者手动设置smp_affinity。我个人习惯手动绑定,因为irqbalance有时候会乱跳。

# 查看中断号
cat /proc/interrupts | grep ens3f0np0

# 手动绑定中断到CPU核心(以中断号130为例)
echo 1 > /proc/irq/130/smp_affinity
# 1 表示 CPU0,2 表示 CPU1,4 表示 CPU2,以此类推
📊 性能对比: 我在一个32核的服务器上做过测试。RSS队列数从1增加到32,NVMe over Fabrics的IOPS从80万提升到了450万,延迟从120微秒降到了45微秒。效果立竿见影。

好了,网络基础设施调优就聊到这儿。这四个点——RoCE v2、PFC/ECN、MTU、RSS——每一个都是性能的关键。你配置的时候,记得端到端检查,别漏了任何一个环节。