2. RoCEv2协议栈与报文结构
RoCEv2(RDMA over Converged Ethernet version 2)是当前 NVIDIA AI 集群中最主流的 RDMA 承载方式。它把 InfiniBand 的可靠传输语义搬到以太网/IP 之上,使 GPU 之间可以用标准以太网交换机构建大规模无损网络。理解 RoCEv2 的关键,不是记住“它跑在 UDP 上”,而是看清三层封装如何协作:以太网负责逐跳转发,IP 负责跨子网寻址,UDP 负责把 RDMA 报文送进正确的队列,而真正决定“这是读还是写、要不要确认、拥塞怎么反馈”的,是紧随 UDP 之后的 BTH 头。
从 IB 到 RoCEv2:语义保留,承载替换
InfiniBand 定义了一套完整的 RDMA 传输层:QP(Queue Pair)成对出现,SQ 发请求、RQ 收请求,通过 Send/Receive、RDMA Read、RDMA Write 等操作完成内存到内存的直接搬运。RoCEv1 把这套传输层直接压在以太网二层之上,使用 Ethertype 0x8915,因此只能在同一个二层广播域内工作,无法跨 IP 子网路由。RoCEv2 的改动非常克制:保留 IB 传输层语义和 BTH 头结构,但把承载从二层改为 UDP/IPv4 或 UDP/IPv6,目的 UDP 端口固定为 4791。这样 RoCEv2 报文就可以像普通 IP 报文一样被三层路由,AI 集群因此可以跨越多个 Leaf-Spine 子网扩展。
需要特别注意的是,RoCEv2 并没有把可靠性交给 TCP。它仍然依赖 IB 传输层的 ACK/NAK、重传和滑动窗口机制,UDP 只提供多路复用和校验,不提供重传。因此网络侧必须做到“无损”或“近无损”,否则丢包会触发 RDMA 重传,时延和吞吐都会明显恶化。这也是 ECN 和 PFC 在 RoCEv2 中如此重要的原因。
报文结构:从以太网头到 BTH
一个典型的 RoCEv2 数据报文从外到内依次是:以太网头(14 字节,含目的 MAC、源 MAC、Ethertype 0x0800)、IPv4 头(20 字节,协议号 17 表示 UDP)、UDP 头(8 字节,目的端口 4791)、BTH(Base Transport Header,12 字节),之后是可选的扩展头(如 RETH、ImmDt、AETH)和 RDMA 载荷。BTH 是 RoCEv2 的“控制核心”,其字段含义如下:
- OpCode(8 bit):标识操作类型,例如 RC Send Only、RDMA Write Only、RDMA Read Request、RDMA Read Response、ACK 等。接收端靠它决定如何处理后续载荷。
- SE(Solicited Event,1 bit):置 1 时表示该消息需要接收端产生完成事件,常用于 Send/Receive 语义。
- M(MigReq,1 bit):迁移请求,用于 QP 状态迁移。
- Pad(2 bit):载荷填充字节数,保证报文 4 字节对齐。
- TVer(4 bit):传输头版本,RoCEv2 中为 0。
- Partition Key(16 bit):分区键,用于逻辑隔离,类似 VLAN 但作用于传输层。
- Reserved(8 bit):保留位。
- Destination QP(24 bit):目的队列对编号,接收端据此把报文投递到正确的 QP。
- A(AckReq,1 bit):请求对方回复 ACK。
- PSN(Packet Sequence Number,24 bit):包序列号,用于检测丢包、乱序和重复,是重传机制的基准。
对于 RDMA Write 和 Read Request,BTH 之后还会跟一个 RETH(RDMA Extended Transport Header,16 字节),其中包含 Virtual Address(64 bit)、Remote Key(32 bit)和 DMA Length(32 bit),分别告诉远端“写到哪个虚拟地址、用哪个 rkey 授权、写多长”。Read Response 和 ACK 则可能携带 AETH(Ack Extended Transport Header,4 字节),其中的 Syndrome 字段携带 ACK/NAK 类型和拥塞提示。理解这些头的顺序和长度,是抓包分析和故障定位的基础。
ECN 与 PFC:两种互补的拥塞控制手段
RoCEv2 网络要同时解决两个问题:一是“不要丢包”,二是“不要拥塞”。PFC(Priority Flow Control)解决前者,ECN(Explicit Congestion Notification)解决后者。PFC 工作在二层,通过 PAUSE 帧按优先级反压上游端口。当交换机某个优先级队列的缓冲区超过阈值时,它向上一跳发送 PFC PAUSE,要求对方暂停发送该优先级的流量。RoCEv2 通常把 RDMA 流量映射到 PCP 3 或 PCP 4,并在交换机上为该优先级配置无损队列。PFC 的优点是反应快、能彻底避免丢包;缺点是可能引发 Head-of-Line Blocking 和 PFC 风暴,因此必须配合合理的阈值和 watchdog 机制。
ECN 工作在三层,利用 IP 头的 ToS 字段。发送端把报文标记为 ECT(0) 或 ECT(1),交换机在队列长度超过阈值时把 ECN 字段改为 CE(Congestion Encountered),接收端收到 CE 后生成 CNP(Congestion Notification Packet)回送给发送端,发送端据此降低发送速率。NVIDIA 的 DCQCN 算法就是基于 ECN 的端到端拥塞控制。实际部署中,ECN 和 PFC 通常同时启用:ECN 负责平滑降速,PFC 作为最后一道防线防止丢包。ECN 阈值设置过低会导致过度降速,过高则 PFC 频繁触发,需要根据链路带宽和 RTT 调优。
协议交互流程:一次 RDMA Write 的完整旅程
以一次 RC(Reliable Connection)模式的 RDMA Write 为例,交互流程如下。发送端应用提交 WR(Work Request),HCA 生成 RDMA Write Only 报文,BTH 中 OpCode 设为 RDMA Write Only,A 位置 1 请求 ACK,PSN 从当前发送窗口取下一个值。报文经 UDP/IP/Ethernet 封装后发出,目的 UDP 端口 4791。交换机根据 DSCP/PCP 把报文送入无损队列,若队列深度超过 ECN 阈值则标记 CE。接收端 HCA 收到报文后,校验 PSN 是否连续,按 RETH 中的虚拟地址和 rkey 把数据直接写入应用缓冲区,然后生成 ACK 报文回送。ACK 的 BTH 中 OpCode 为 ACK,PSN 为被确认的包序号,AETH 中 Syndrome 表示 ACK 类型。发送端收到 ACK 后释放对应 WQE,完成事件写入 CQ。如果接收端检测到 PSN 跳变,会回 NAK 并触发发送端重传。整个过程对应用透明,CPU 几乎不参与数据搬运。
udp.port == 4791,然后展开 InfiniBand 解析树查看 BTH 的 OpCode、PSN 和 AETH 的 Syndrome。若看到大量 NAK 或 PSN 不连续,优先检查链路误码、PFC 配置和 ECN 阈值,而不是先怀疑应用。
关键参数速查
| 字段/参数 | 位置 | 典型值/说明 |
|---|---|---|
| Ethertype | 以太网头 | 0x0800(IPv4) |
| IP Protocol | IPv4 头 | 17(UDP) |
| 目的 UDP 端口 | UDP 头 | 4791 |
| BTH 长度 | UDP 载荷起始 | 12 字节 |
| RETH 长度 | BTH 之后 | 16 字节(Write/Read Request) |
| AETH 长度 | BTH 之后 | 4 字节(ACK/NAK) |
| PFC 优先级 | 以太网 PCP | 通常 3 或 4 |
| ECN 标记 | IP ToS | ECT(0)/ECT(1)/CE |