03.高速互联:无损网络 RoCEv2#
Author by: 焦方正
大模型参数从万亿级向十万亿级迈进,算力集群从“万卡”扩展至“十万卡”规模,传统网络带宽瓶颈与丢包问题成为制约算力效率的关键因素。无损网络通过实现零丢包、低时延、高吞吐的数据传输,确保大规模分布式训练任务效率,是释放万亿参数模型潜力的关键底座。
无损网络的必要性#
为了实现内核卸载,达到高带宽、低延时的传输目的,RDMA 在设计之初便要求将所有网络协议栈卸载到网卡(RNIC)进行,以规避 CPU 参与传输过程。在应对丢包时的重传策略选择上,传统 TCP 的缓存并乱序重组的方案对网卡的缓存资源和处理能力要求极高。同时,RDMA 设计之初是基于 IB 网络,其采用的逐跳的、信用的控制方式很难产生丢包,因此在重传策略上,选择了简单高效的 go-back-N 的方式,即默认网络不会产生丢包,一旦接收乱序,便进行丢弃重传。
在 RoCE 网络中,通常使用 RoCEv2 来实现大规模的互联互通。RoCEv2 采用 UDP 的无连接不可靠传输协议,不像 TCP 协议这样的可靠传输机制,具有滑动窗口、确认应答的机制。而 RDMA 的重传策略又采用 go-back-N 的方式,因此在以太网络上丢包对 RDMA 的传输性能影响极大。
在不考虑链路误码这种非正常情况,数据传输过程中所有交换设备理论上都可以按照设计的线速转发传输数据包。但是一旦数据传输出现争抢,如两条链路的流量需要一个端口进行转发,数据包就会在该入端口的缓存进行排队。我们把这种现象称作 incast。每个端口的缓存 Buffer 大小有限,一旦超过这个端口的缓存能力,端口会将无法缓存下来数据包丢弃,从而产生丢包。如前文说所,RDMA 对丢包十分敏感,因此为了防止丢包产生,交换机需要预先采取相应的措施来避免这种情况发生。因此,便推出基于优先级的流量控制(Priority Flow Control,PFC)机制来实现无损网络。
PFC 协议原理和特点#
PFC 是 IEEE 802.1Qbb 标准定义的链路级流量控制协议,核心目标是为不同优先级流量提供独立的无损通道。所谓的不同优先级也是由IETF和IEEE标准组织定义的服务类别标准。在802.1p标准中,用三个bit位提供了8种服务类型,对应8个队列。详细内容如下表所示:
IP层 (DSCP) |
含义 (PHB) |
典型应用 |
映射到的数据链路层 (802.1p 优先级) |
解释 |
|---|---|---|---|---|
EF (46) |
加速转发 |
语音流量 |
5 |
最高优先级,对应极低延迟、低抖动的流量 |
AF4x (34, 36, 38) |
保证转发4 |
交互式视频 |
4 |
高优先级,需要保证带宽和低延迟 |
AF3x (26, 28, 30) |
保证转发3 |
流媒体视频 |
3 |
中等偏高优先级,需要保证带宽 |
AF2x (18, 20, 22) |
保证转发2 |
关键业务数据 |
2 |
标准的数据优先级,有保证的交付 |
AF1x (10, 12, 14) |
保证转发1 |
尽力而为数据 |
1 |
低于标准数据,但优于背景流量 |
CS0 (0) |
尽力而为 |
标准网络流量 |
0 |
默认优先级,无特殊要求 |
CS1 (8) |
低优先级数据 |
清道夫流量 |
1 |
用于不影响关键业务的流量(如个人备份) |
通常我们会将这些服务与交换机的8个缓存队列建立映射关系,从而实现在不同的转发队列上实现不同的服务类型。

如上图所示,交换机上的流量根据不同的服务要求,在不同队列上进行转发。PFC 是数据链路层上的点对点的流量控制协议,基于上述这8个队列,我们可以单独为每个队列使能并配置PFC协议来实现队列级的无损队列实现。PFC协议的核心功能就是在某个队列满足要求时,让上游端口停止发送。整个过程使用 Xon 和 Xoff 两个队列缓存包的大小进行控制。
当接收端交换机/网卡检测到某优先级队列的缓冲区大小积累的数据包量超过 Xoff 时,便会立刻向上游发送 PFC 暂停帧(Pause Frame)。上游设备收到后,会立刻停止该优先级流量的发送,其他优先级流量不受影响。随着上游停止发送,下游持续转发,入口缓冲区大小逐渐下降,当达到 Xon 大小时,会向上游端口发送恢复帧(Resume Frame)。每个队列拥有单独的计数器,如上图所示,在8个队列中,其中队列7的数据包缓存数量触发了Xoff,发出Pause帧使得该队列的数据发送停止。总的来说,PFC是根据每个队列深度,实现在发生丢包前,让上游停止发送的无损控制机制。
通过 PFC 的机制可以总结出 PFC 协议具有以下几个特点:
点对点控制协议,链路两端通过相关的控制帧,实现流量发送的启停。
流量控制过程是粗暴地、无脑地。只存在发和不发两个状态,一旦 Xon 发送不及时,容易降低带宽利用率。
控制时延是一跳,Xoff 参数剩余的空间必须能够存储一个带宽时延积的数据包大小才能保证 Pause 生效前,吸收链路上 flight 的数据包。
只按照队列进行区分,并不能区分流量,因此在多流环境下,进入同一端口的流量都会受到影响。
PFC 协议存在的问题#
如上所说的 PFC 特点,在实际环境中,PFC 还存在一下四个主要问题:
队头阻塞(Head-of-Line Blocking)。PFC 的控制粒度是按照是优先级队列。一个优先级队列中通常存在多个不同的数据流。当该队列因其中一个流出现拥塞,上游该优先级的通道都会被暂停。这意味着,该队列中所有无关的数据流都会被阻塞,即使它们的目的地端口空闲且没有任何拥塞。如下图所示。

图(a)表示来自下游的Pause帧使得从Egress1发出的f1流量首先在出口处堆积,并很快蔓延到入口方向,如图(b)所示。由于f2流量也由Ingress1进入,f1造成的阻塞导致f2的数据包同样在交换机队列中排队,无法正常转发,从而造成队头阻塞。
不公平。当 Pause 帧产生,同时向 C 端口发送的 AB 两个端口入端口的上游同时停止,当 Resume 帧发出,AB 两个端口又同时开始发送数据。如果 A 端口只接收一个流,而 B 端口有两个流,由于同时开始这个过程,B 中的两条流同时与 A 中的一个流竞争,导致 A 的流量占据一半带宽。如下图所示。

初始状态下,f1、f2、f3是均等的进入到出口队列Egress1中。当出现拥塞并恢复发送后,f2与f3同时与f1竞争,导致三条流量的比例变为2:1:1,f1独享一半的带宽。我们把这种情况称为PFC引发的办公平现象。
PFC 风暴。由于 PFC 策略是点到点的控制,并不能直接降低源头的发送速率,所以当前方出现拥塞而发送方还在持续发送时,PFC 会逐级反压,甚至直接传导到发送方。该过程会产生大量的 Pause 帧,从而使链路发送停滞,由于队头阻塞的影响,收到影响的链路范围也越来越广,从而产生风暴。
PFC 死锁。当 PFC 产生逐级反压时,一旦网络中存在环路(配置错误,路由收敛时的瞬时环路,设备故障等),PFC 将会形成环形暂停从而造成死锁,所有端口都无法发送数据,队列挤压,同时向上游端口发送暂停。这种相互等待一旦发生。没有外力干预几乎不可能自己恢复。
队头阻塞的缓解方法有多种,从配置上可以将流量按照流量的特点分配在不同的队列上。而对于PFC死锁问题,除了在配置上尽快避免环路的发生,交换机也会有类似watchdog的方式来避免死锁,当pfc暂停一定时间后主动解除暂停状态,允许丢包并恢复数据的传输,以此来降低PFC死锁的产生。最根本的解决办法在于尽快少的触发PFC,在后续拥塞控制协议的介绍中,我们会介绍如何利用ECN来处理PFC带来的诸多问题,从而更好的处理incast下的流量控制问题。
总结与思考#
本节重点介绍了PFC协议的基本原理,并对PFC带来的一系列问题做详细的分析。总的来说,PFC是一个点对点的无损控制协议,其本质的出发点是尽可能快的避免接收端口丢包,但由于它并没有从根源上降低发送速度,这部分数据的缓存压力会逐级的向上反压。PFC协议是保证无损必不可少的条件,但在其后,又提出了诸多更好的解决拥塞控制这个话题的算法。