网络基础设施调优:RoCE v2 配置、PFC/ECN 流控、MTU 巨帧设置、网卡多队列(RSS)绑定
各位好,咱们接着聊NVMe over Fabrics的性能优化。上一章我们把目光聚焦在CPU和内存上,这一章,我们把视线拉到网卡和交换机上。
说白了,NVMe over Fabrics跑的是存储协议,对网络的延迟和吞吐要求极高。你想想看,一个NVMe命令的延迟,如果网络部分占了50微秒,那整个IO路径就废了。所以,网络基础设施的调优,是绕不开的一环。
我个人习惯,先把网络调优分成四个维度:协议卸载(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放行这个端口。
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风暴——一个队列堵了,整个链路都停摆。
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,以此类推
好了,网络基础设施调优就聊到这儿。这四个点——RoCE v2、PFC/ECN、MTU、RSS——每一个都是性能的关键。你配置的时候,记得端到端检查,别漏了任何一个环节。