3、RoCE协议详解:RoCE v1与RoCE v2的区别、RoCE v2的UDP封装、流控机制(PFC/ECN)

好,咱们直接进入正题。RoCE这个协议,说白了就是让RDMA能跑在以太网上。你想想看,以前InfiniBand虽然快,但贵啊,而且和现有的以太网生态不兼容。RoCE的出现,就是为了解决这个痛点。今天这一讲,我会把RoCE v1和v2的区别、UDP封装细节,以及PFC和ECN这两个流控机制,掰开了揉碎了讲清楚。

3.1 RoCE v1 vs RoCE v2:到底差在哪?

RoCE v1是最早的版本。它的设计思路很简单——直接把InfiniBand的报文封装到以太网帧里。这意味着什么?意味着它只能在同一个二层网络里跑,不能跨网段。我记得在2015年左右,有个客户想用RoCE v1做跨机柜的存储同步,结果发现交换机一多,延迟就飙上去了。后来一查,原来是广播域太大,ARP风暴把网络打满了。

RoCE v2就不一样了。它引入了UDP封装,把RDMA报文放到了UDP payload里。这样一来,它就能跑在三层网络上了。你想想看,三层网络意味着什么?意味着可以路由、可以跨子网、可以走传统的IP网络。我个人的习惯是,只要条件允许,一律用RoCE v2。原因很简单——灵活性高太多了。

核心区别总结:
  • RoCE v1: 基于以太网类型字段(0x8915),二层通信,不能路由。
  • RoCE v2: 基于UDP封装(目标端口4791),三层通信,支持路由。
  • RoCE v2的头部开销: 多了UDP头部(8字节)+ IP头部(20字节),但这点开销在万兆/25G网络下几乎可以忽略。

嗯,这里要注意。虽然RoCE v2支持路由,但并不是所有交换机都能很好地处理RDMA流量。我曾经在一个项目中遇到过,某品牌的低端交换机,开启路由后,RoCE v2的吞吐量直接掉了一半。后来排查发现,是交换机的转发芯片对UDP封装的支持不够好。所以,选型的时候一定要确认交换机的RoCE能力。

3.2 RoCE v2的UDP封装:细节决定成败

RoCE v2的UDP封装,说白了就是把RDMA的传输层(RC、UC、UD)报文,塞进UDP数据段里。目标端口固定为4791,源端口可以随机。为什么要固定目标端口?因为这样交换机就能通过ACL或者流规则,快速识别出RoCE流量,然后做优先级标记。

我建议你在配置的时候,注意一下UDP校验和。RoCE v2规范里,UDP校验和是可选的。但如果你关掉了校验和,一旦网络中出现比特错误,RDMA层是感知不到的。这会导致数据静默损坏。我在一个金融客户那里就踩过这个坑——他们为了省那点CPU开销,关掉了校验和,结果跑了一周后,数据库里出现了坏块。嗯,从那以后,我再也不敢建议关校验和了。

我的经验: 在RoCE v2的UDP封装中,源端口建议使用哈希算法生成。这样可以让RoCE流量均匀分布在多个队列上,提高多核处理器的利用率。你可以用 ibdev2netdev 命令查看当前网卡的RoCE配置。

3.3 流控机制:PFC vs ECN

RoCE最大的敌人是什么?丢包。因为RDMA的传输层设计是假设网络不会丢包的,一旦丢包,性能会断崖式下跌。所以,流控机制就成了RoCE网络的命门。目前主流的有两种:PFC和ECN。

3.3.1 PFC(优先级流控)

PFC是IEEE 802.1Qbb标准定义的。它的原理很简单——基于优先级的停等流控。每个优先级队列都有一个阈值,当接收端的缓冲区快满时,它会发送一个PAUSE帧给发送端,让发送端暂停发送这个优先级的流量。

听起来很完美对吧?但实际用起来,问题不少。我遇到过最典型的一个场景:PFC风暴。当网络中出现拥塞时,PAUSE帧会像多米诺骨牌一样,一级一级往上传递,最终导致整个网络的吞吐量骤降。而且,PFC是逐跳的,如果中间有一台交换机配置不对,整个链路都会受影响。

避坑指南: 我曾经在一个超大规模集群里,因为PFC的阈值设置得太激进,导致存储节点和计算节点之间的RoCE链路频繁出现PFC死锁。后来我们把阈值调大了20%,并开启了PFC watchdog,才稳定下来。记住,PFC不是银弹,它需要精细调优。

3.3.2 ECN(显式拥塞通知)

ECN是另一种思路。它不直接停等,而是通过标记报文来通知发送端“网络有点堵了,你慢点发”。具体流程是这样的:

  1. 发送端在IP头部设置ECT(ECN Capable Transport)标记。
  2. 当交换机的队列深度超过阈值时,它会将报文的ECN字段改为CE(Congestion Experienced)。
  3. 接收端收到CE标记后,会在ACK中携带ECN Echo信息。
  4. 发送端根据ECN Echo,动态调整发送速率。

我个人更倾向于ECN。为什么?因为它是一种端到端的拥塞控制,不会像PFC那样引发连锁反应。而且,ECN可以和DCQCN(Data Center Quantized Congestion Notification)配合使用,效果非常好。我在一个AI训练集群里,用ECN+DCQCN的组合,把RoCE的吞吐量从80%提升到了95%以上。

PFC vs ECN 对比表:
特性 PFC ECN
控制粒度 优先级队列级别 流级别
反馈机制 PAUSE帧(停等) ECN标记(速率调整)
部署复杂度 中等(需逐跳配置) 较高(需端到端支持)
典型问题 PFC风暴、死锁 ECN阈值调优困难
推荐场景 小规模、低延迟敏感 大规模、高吞吐需求

3.4 核心逻辑流程图

下面这张图,是我自己画的RoCE v2的报文处理流程。你可以看到,从应用层到物理层,每一步都有对应的封装和解封装。特别是UDP封装和ECN标记的位置,一定要记清楚。

RoCE v2 报文处理流程 发送端:应用层 RDMA传输层(RC/UC/UD) UDP封装(目标端口4791) IP层(设置ECT标记) 以太网/MAC层 交换机 ECN标记/队列 接收端 解封装 ECN Echo RoCE v2 报文 转发报文 ECN反馈(速率调整) 发送端 交换机 接收端 ECN反馈

嗯,这张图里,你重点看两个地方:一是UDP封装的位置,它是在RDMA传输层之下、IP层之上;二是ECN反馈的路径,它是从接收端通过ACK报文,反向通知发送端的。这个流程,我在调优RoCE网络时,反复对照过很多次。

3.5 实战建议

最后,给你几个实战中的建议:

  • 优先使用RoCE v2: 除非你的网络环境极其简单(比如只有两台服务器直连),否则不要用RoCE v1。三层网络的灵活性,值得你多花那点配置时间。
  • ECN + DCQCN 是黄金组合: 我建议你在数据中心里,优先部署ECN。如果交换机不支持ECN,再考虑PFC。但PFC一定要配合watchdog使用,防止死锁。
  • UDP校验和不要关: 别为了那点性能提升,冒数据损坏的风险。尤其是在存储场景下,数据完整性是第一位的。
  • 监控队列深度: 不管是PFC还是ECN,队列深度都是关键指标。你可以用 ethtool -S 查看网卡的统计信息,重点关注 ecn_markedpfc_pause 这两个计数器。
一个小技巧: 在部署RoCE v2之前,先用 iperf3 打一下UDP流量,确认网络中没有丢包。然后再用 ib_write_bw 测试RDMA带宽。如果这两个测试都通过了,RoCE基本就稳了。

好了,这一讲的内容就到这里。RoCE的协议细节比较多,但只要你理解了v1和v2的区别、UDP封装的要点,以及PFC和ECN的适用场景,后面配置和调优就会轻松很多。

专注资料整理