千家信息网

如何设计高性能RoCE网络

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章给大家分享的是有关计高性能RoCE网络的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。一、低开销高性能的无损网络选型普通的内网进行数据包交互时,通常会使用系统级的TC
千家信息网最后更新 2025年12月02日如何设计高性能RoCE网络

这篇文章给大家分享的是有关计高性能RoCE网络的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

一、低开销高性能的无损网络选型

普通的内网进行数据包交互时,通常会使用系统级的TCP/IP协议栈或者是DPDK技术,这两种方案都是依靠软件进行协议栈解封装的,对系统的CPU有不少消耗。而有一种方案:RDMA,可以直接使用网卡进行协议栈解封装,无需消耗系统CPU,能有效降低数据处理的延时。

RDMA并没有规定全部的协议栈,比如物理链路层、网络层、传输层每个字段长什么样,如何使用,但对无损网络有相当高的要求:

- 不轻易丢包,重传带来的延时非常大。

- 吞吐量巨大,跑满最好。

- 延时越低越好,100us都嫌长。

依据上述要求,主流的网络方案有三种:

图:主流的RDMA网络方案

① InfiniBand: 该方案重新设计了物理链路层、网络层、传输层,是RDMA最初的部署方案,所以要使用专用的InfiniBand交换机做物理隔离的专网,成本较大,但性能表现最优;

② iWARP: 该方案的目的是让主流的以太网支持RDMA,将InfiniBand移植到TCP/IP协议栈,使用TCP协议保证无丢包,但缺点在于TCP开销较大,且算法复杂,所以性能表现较差;

③ RoCEv2: 该方案的目的也是让主流的以太网支持RDMA(RoCEv1版本已很少提及了)。网络侧使用PFC保证拥塞时不丢包,网卡侧又使用DCQCN的拥塞控制算法进一步减缓拥塞(该拥塞算法需要网络侧支持ECN标记),传统的以太网经过PFC和ECN的加持进化成为无损以太网,在无损以太网上运行RDMA性能大大增强。

RoCEv2(后文简称RoCE)方案的成熟案例较多,我们也选用了该方案进行研究。但RoCE方案仍存在一些问题,如PFC压制的不公平性、PFC传递带来的死锁风险、过多的调参、ECN标记的滞后性(ECN概率标记是软件轮询机制)等,是需要我们解决完善的。

二、网络设计的目标

要把RoCE搬到经典的数据中心网络上,这可不是一件容易的事儿。

当前数据中心是常见的CLOS架构,LCS是汇聚交换机,LAS是TOR交换机。如果RoCE直接运行在这上面,问题是显而易见的:例如出现Incast事件时,转发不了的报文会被存放在交换机缓存中,但缓存也不是无限大的,如果存满了,这个数据包就丢掉了,很明显这种丢包频率肯定不能被RDMA所接受。

图:CLOS架构示意

上面只是举了一个简单的例子,实际上出现的问题要更复杂一些。在设计之前,需要先明确好我们的目标是什么,做到有的放矢。

简单来讲我们的目标就是:

- 在各种流量模型下,网络带宽要能跑满;

- 缓存使用要尽可能低;

- 极限情况下缓存使用满了也不能丢包。

总结来说,为了让RoCE跑在已有的网络上,我们需要从三个方面下手:
① QOS设计:指队列、调度、整形等一系列的转发动作,相对独立。

② 无损设计:是RDMA的要求之一,使用PFC技术实现。无损是一种基本保障,含义是在最拥塞的情况下也能保证其可用性,让上层应用可以放心发送数据,不必担心丢包的风险(所以说PFC并不是降速的手段)。

③ 拥塞控制设计:使用DCQCN技术实现。拥塞控制是满足基本保障前提下的进一步优化,含义是在开始拥塞的时候,就告知服务器两端,使其从源端开始降速,从根本上解决问题。

补充一点拥塞带来的坏处:当出现拥塞后,必然要使用缓存,使用缓存后虽然不丢包了,但是带来的后果是延迟上升,而且吞吐也不能再增加一丝一毫。网络中拥塞点有很多,每一跳都可能成为拥塞点,在上图的网络中,最多会有3个拥塞点。

缓存的使用能带来多少延时?

我们按25Gbps来算,缓存25Mb的数据,大约需要1ms的时间才能发送完毕,25Mb也仅仅是3.1MB,而常见的Broadcom Trident 3芯片有32MB的缓存。

有了这三个方面的认识,我们就可以化繁为简,逐一破解。

三、QOS设计

QOS的设计,无非是入队、调度、监管和整形。

入队方式可以依据DSCP、TOS、COS等标记,然后信任某种标记入队,也可以选择使用策略抓取其它报文特征入队。我们最终选择的策略是:在IDC边界处,使用报文特征抓取入队,并重写DSCP,IDC内部仅根据DSCP入队(IDC内部减少策略使用,满足高速转发即可)。这样,既能保证DSCP标记的可信任,又能减轻IDC内部的策略复杂度。根据这个思路,我们分别设置对应策略:

- 对ToR下行端口与Border上行端口: 抓取特定报文,进入特定队列。

- 对其余设备和端口设置:信任DSCP,按映射入队。

用图表表达即:

■ IDC边界入队

次序

Match

Action

1

udp_dport==4791 &&
dscp==48

入队列6

2

udp_dport==4791 &&
dscp==46

入队列5

其他

其他

修改dscp为预定义

*这是已有的标记策略,我们IDC内部为业务进行分类,并标记特定的DSCP。

*其中次序1、2只在RoCE网络的ToR部署。

■ IDC内部DSCP映射

DSCP

队列

48

6

46

5

其他

2…

下面该聊聊调度设计了,调度的对象是缓存中的数据,也就是说,调度是仅在拥塞时才生效的,而且调度生效后,影响的将是各队列的流量大小。

带着以上的认识,我们开始调度设计。在一般的RoCE网络中,使用的有如下队列(或流量):

① 协议信令类,目前来看只有CNP流量;(其它协议均不跨跳,所以不考虑)

② RoCE流量;

③ 业务/管理流量。

这三大类流量,还可以继续分小类。按照ETC所推荐的调度模型,我们选择了SP+WDRR的调度方式,即:1类流量绝对优先,在缓存积压的时候优先调度,直到队列为空。2类和3类流量次优,两者之间按照WDRR调度,权重值可以灵活定义。这样就能保证CNP报文在3us内转发给流量源站(没有拥塞的网络单跳的延时在1us以内)。

以上调度设计中有个漏洞:如果队列6的流量过大,可能会将低优先级的队列饿死(即长时间得不到调度),虽然理论上队列6的流量一般都在几十~几百Mbps,但仍要提防服务器恶意***行为。于是,我们将SP的队列限制其队列使用带宽。这个便是所谓的监管和整形了。

四、无损涉及与分析

RoCE的流量需要保证运行在无损队列中,无损队列使用了PFC技术,能针对某一队列发送Pause帧,迫使上游停流。

在博通的XGS系列芯片中,有一块缓存管理单元MMU(简称缓存),存放已收到但没转发走的报文,并给入口和出口都计数:"0/1的入口和0/2的出口,都用了1个cell"(cell是缓存资源的最小单位)。

缓存会给每个入口和出口设置一个上限,超过这个上限就不能再使用cell缓存报文了。上限以下还画了很多其它的水线,同时对每一个出口和入口进行进一步细分,可以按照队列进行统计限额其中入方向。入方向上,细分了PG-Guaranteed大小、PG-Share大小、Headroom大小;出方向上,细分了Queue-Guaranteed大小,Queue-Share大小(如下图所示,这里我们不考虑端口,只考虑队列)。

图:队列入方向与出方向示意

缓存使用的时候,总是从下往上依次申请使用,所以更喜欢把这些区块大小称之为"水线",当"某区块"都使用完毕,就称之为"缓存水位"到达了"某水线"。例如:当PG-Share区块使用完毕,就称之为,入口缓存水位已经到达PG-Share水线。如果所有区块用完就产生丢包了,称为no buffer丢包。

每一块大小都有其特殊用处,先简单看下其作用,后面再探讨下无损队列中的这5个水线应该如何设置。

►PG-GuaranteedQueue-Guaranteed是保证缓存,这部分是独享的,即使不用,别的队列也不能抢占使用。

►PG-ShareQueue-Share使用的是共享缓存,因为动态水线的缘故,它们的大小不固定,如果很多队列都在用,那平分一下,每个队列的水线就都很小。另外,PG-Share还有另一个重要的作用:PFC发送的临界点,也称为xoff水线,只要到达该水线,PFC就会从这个口发出去,回落一些后,才恢复正常。

►Headroom是一个特殊的水线,只有在无损队列中才能发挥其作用。设想一下,PFC发出去以后,流量真的能瞬间停下来么?答案是不能的!因为线缆中还有一部分数据,而且七七八八的转发处理时间也要算进去。所以Headroom空间就是用来做这个的。

**1、PG-Guaranteed和Queue-Guaranteed

**

讲完了基本原理,回过头来看网络设计。先看PG-Guaranteed和Queue-Guaranteed水线,这俩水线与"无损队列"关系不大,保证缓存的作用只是满足交换机基本的存储转发功能,所以配置为一个数据包大小即可。那我们按照最差的情况来算,即MTU=9216的巨型帧。

但实际上我们不必为此发愁,因为动态水线的缘故,共享缓存中总会有剩余的缓存以供使用,所以保持原厂的默认配置即可。

2、Queue-Share

接下来是Queue-Share水线。在无损队列中,我们希望在缓存丢包前,能触发PFC进行反压,所以在任何情况下,都应该入口PG-Share先到达水线,出口Queue-Share永远不能到达水线(PG-Share到达会发PFC,Queue-Share到达会丢包)。

之前讲过,MMU记账是出口入口各记一笔,这样来看,最差情况应该是多打一(出口的帐全记在一个队列上,入口的帐会均摊到不同队列中)。为了让出口水线永远不会到达,索性将出口水线配置为无限大好了,事实证明这样做也没有问题,因为入口的PG-Share是动态水线,总能在Buffer破产前触发该水线。

这样一来,Queue-Share好像已经搞定了,其实不然,如果TCP流量参与进来混跑呢?这问题可就严重了,TCP的Lossy队列会吃掉大量缓存,所以Lossy队列中,对应的Queue-Share水线也应当限制一下。

3、PG-Share

PG-Share水线只要配置为动态水线即可,大小可以随意调节,都不会出太大问题的,但需要满足一个不等式:(PG-Share + PG-Guarantee + Headroom) * [入口个数]≤ Queue-Share + Queue-Guarantee

该公式描述的是一个端口多打一的场景。入口个数根据实际情况选取一个较大值(拿ToR来看,最差情况是39打1,32个25G下行,8个100G上行)。

这里的PG-Share是动态水线,动态水线用一个简洁的公式即可表达:PG-Share = [剩余Buffer] * α

这里的α是缩放因子,用户可自由调节。可以看出,缩放因子决定了PG-Share水线的大小。依据上面等式,我们只要将Queue-Share水线设置为静态最大、PG-Share设置为动态即可,入口的缩放因子α可随意。当然入口α也不能设置太小,在端口少打多的情况下,由于入口的水位很低,导致均摊到每个出口时,出口的水位更低!出口的水位过低时,会发现已有的ECN配置不再生效(例如:可能出口的水位还到不了Kmax的一半)。在我们的经验看来,无损队列中PG-Share的α,配置1/8,1/4,1/2,1都可以,具体大小还要联合拥塞设计中ECN参数来决定。

4、Headroom

Headroom水线很重要,但可以通过实验+推导的方式得出合理的配置,先来看一个等式:[Headroom大小] = [PFC构造到停流的时间] * [端口速率] / [64字节小包占用的比特数]

使用64字节小包计算,是因为小包对缓存的使用率最低,单个Cell有200多字节,但只能被一个报文独享。其中,只有[PFC构造到停流的时间]是需要进一步分解的:T = Tm1 +Tr1 + Tm2 +Tr2* Tm1:下游PG检测到xoff用完,到构造PFC帧发出的时间。

* Tr1:PFC帧从下游发往上游的时间。

* Tm2:对端收到PFC帧,到队列停止的时间。

* Tr2:队列停止后,线缆中报文传输的时间。

可以看出,这四个时间中,只有线缆长度是变量,继续化简后可以得出:[Headroom大小] = (Tm1 + Tm2 +2 * [线缆长度] / [信号传播速度]) * [端口速率] / [64字节小包占用的比特数])

这里面Tm1 + Tm2 是常数,可以实验测得,剩余的都是已知量了。最后根据公式就可以算得100G口,100M光纤下,H = 408 cell;25G口,15M AOC下,H = 98 cell。当然,真正使用的时候,还要再冗余一点,毕竟这是临界值。

5、死锁分析和解决

谈到PFC就不得不提一下死锁,死锁危害极大,而且其传递性会迅速扩散到整个网络,以至于整个网络的无损队列全部停流。死锁的研究很多,其中较详细的是微软的一篇论文《Deadlocks in Datacenter Networks: Why Do They Form, and How to Avoid Them》。

死锁产生的一个必要条件是CBD(环状缓存依赖),在我们的组网环境中,是典型的CLOS组网,所以在稳定状态下不会存在CBD,也没有死锁风险。而且整个POD内部路由不做过滤,明细互知,汇聚采用4台~8台冗余,即使出现两点故障,收敛后的拓扑也不会存在CBD,即不会存在死锁风险。

图:CBD和死锁

至此,我们已经解决稳定状态下的死锁了,但还要考虑一点:收敛过程中,是否存在CBD?其实仔细分析一下还是会存在的,我们考虑了很多收敛场景,确实会有部分场景下,存在微环路。有微环路就一定有CBD。事实证明,我们也真实地模拟出了微环路导致的死锁。

死锁问题总是要解决的。我们使用三种方法:

1、针对各种微环路场景,通过设计网络协议,控制收敛的现先后关系,避免出现微环路出现。

2. 对于其它未知的死锁风险,使用交换机的死锁检测功能,释放缓存(释放缓存会产生丢包,但收敛过程本身就有乱序/丢包情况)。

3. 将PG-Share的水线适当拉高,尽量使用DCQCN拥塞控制来压制流量。

五、拥塞控制设计与分析

网络拥塞控制是一个很复杂的课题,这里只讲一些基本的设计思路。
RoCE使用的拥塞控制算法是DCQCN,_《Congestion Control for Large-Scale RDMA Deployments》_这篇论文很详细地描述了该算法。

这里先简单的描述下这个算法:维护这个算法的节点是服务器,也就是流量的两端,中间的交换机作为传输节点,通告是否拥塞。发送方叫Reaction Point,简称RP;接收方叫Notification Point,简称NP;中间交换机叫 Congestion Point,简称CP。发送方(RP)以最高速开始发送,沿途过程中如果有拥塞,会被标记ECN显示拥塞,当这个被标记的报文转发到接收方(NP)的时候,接收方(NP)会回应一个CNP报文,通知发送方(RP)。收到CNP报文的发送方(RP),就会开始降速。当发送方没有收到CNP报文时,就开始又提速了。

上述过程就是DCQCN的基本思路。虽然整个算法十分复杂,但都是围绕这个基本思路,继续完善算法细节(下图分别是NP的状态机和RP的算法)。可调参数也十分众多,比如降速要降低多少?提速效率是否积极?网络拥塞度如何维护?拥塞度更新周期多久?CNP报文的敏感度多大?这都是问题,需要对流量建模后找出合理参数。

图:接收方

图:发送方

DCQCN算法中,对RP、NP和CP都有很多参数可以调节。RP和NP节点在服务器上,准确来说应该是在网卡上,网卡初始化的参数已经为最优值,无需再进行调整,这样就剩CP上的参数需要调整了。

CP上有三个参数其实就是WRED-ECN的那三个参数,分别是Kmin,Kmax,Pmax,这三者的关系,可以用下图来表示。横轴是出向队列长度,纵轴是报文被标记的概率。从图中可以看到,在队列长度超过Kmax时,标记概率出现一个跳变,从Pmax直接到达100%。

根据上面的理论分析,我们可以通过实验证实和试错的方法一步步找到最优解。

现在设想一下:在一个拥塞场景中,当出口队列长度小于Kmin时,不会被标记,出口队列长度可能会稳步增长,当队列长度超过Kmin时,DCQCN才开始降速。
所以Kmin的大小决定了RoCE网络的基础延时,这些缓存中的报文是发送者发出,但未被接收者确认的报文,我们称之为inflight bytes,约等于延时带宽积。所以,Kmin的配置规范为小于期望的延时带宽积。有了这个理论基础后,实践测得理论符合实际,还可以根据测得的延时进一步调整该数值。

我们用同样的思路来思考Kmax,承接刚刚的思路,那就是:Kmax的配置规范为小于或等于能容忍的延时带宽积。但这次不再这么简单了,因为Kmax还决定了图中的斜率。同样决定斜率的还有Pmax,在讨论Kmax和Pmax前,我们不得不先介绍下整个ECN的理想与现实。

理想状态下,标记概率在定义域Kmin~Kmax内的变化是连续的,而且,队列的长度是准确的。但事与愿违,博通芯片SDK使用软件轮询的方式测得队列长度,而且将此刻的队列长度与历史值做指数平均,并依此计算标记概率。软件轮询带来的结果是,标记概率在定义域Kmin~Kmax内的变化是不连续的,其次,指数平均值会让测得的队列长度是滞后的(当然指数平均也带来了好处,这里不展开)。

这件事带给我们的影响就是,理论推导的Pmax,甚至Kmin、Kmax都被推翻,请继续往下看:理想状态下,一个25G端口、单QP会话下,最大的有效Pmax是多少?

根据DCQCN中NP的算法,50us内收到多个CE标记包,会被认为只有一个有效包,所以最高的CE标记速率应该为20000个包每秒(即1个包每50微秒),依此,我们算得最高有效Pmax,即是设置的Pmax值,如下表所示:我们假设一个25G端口、只有一个QP会话,此时最高有效Pmax是多少?可以根据表格中第4、5列计算出最后一列最高有效Pmax的值。

再回到现实,我们按照推导的数据对表格最后一行进行验证。

对端口限速模拟拥塞,测得稳定时RoCE流量pps=2,227,007,然后选取一组ECN配置:Kmin=1cell,Kmax=1400cell,Pmax=1%,理论上来说Pmax已经超出最高有效的值了,理论上即使在拥塞时,出口水位也不可能达到1400cell,所以再设置一个监控项,监控出口水位有没有超过1400cell(触发式告警,并非轮询,所以不会存在采集不到的情况)这是第一个实验。

作为对比,第二个实验使用另一组ECN配置,Kmin=800cell,Kmax=1400cell,Pmax=1%,按照之前分析,这一组配置下,出口水位也不会超过1400cell,因为在1400cell水位时,Pmax=1已经超过最高有效标记概率了。

可是实验结果并不符合预期,第一个实验没有触发告警,通过;第二个却触发告警了。这就意味着在某些时刻,缓存水位超过1400cell了!水位是波动的,并没有稳定在某个值!我们大胆猜测其中原因:从缓存队列积压,到得到缓解,这其中有太多地方消耗了时间:队列长度的轮询、指数平均算法、CNP的生成与转发,甚至于降速后线缆中的数据传输等等。

为解决这一难题,我们另辟蹊径,选择了另外一条路:首先制定了几个小目标,然后通过大量的实验来摸索出验证一套安全可靠的配置。这个方法虽然更野蛮,但很有效。

小目标1:服务器端口吞吐量要在95%以上;

小目标2:所有流量场景下交换机99%的时间里PFC发送速率不得高于5pps;

小目标3:任意场景下服务器端到端延时不得高于80us(90%场景下低于40us)。

对于流量模型,我们设计筛选后,选用了50余种流量,最终我们得到了同时满足这三个小目标的合理参数。

不得不说,DCQCN很难玩转,参数众多且互有联系,这里也只是提供一些实践规律,欢迎一同深入探讨。

关于高性能RoCE网络的设计方案就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

队列 缓存 水线 网络 流量 标记 设计 出口 大小 报文 入口 死锁 算法 调度 配置 数据 方案 水位 端口 长度 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 青岛计算机网络技术招聘 sql不会连接服务器是怎么回事 数据库第三级安全标记等级 网络技术防诈骗 倩女幽魂手游怎么增加服务器 梦幻西游2服务器列表 无人驾驶软件开发公司 怎么用旧电脑做实体服务器 互联网引领科技创新人工智能 网络安全产品效果图室内 黄岛区安卓软件开发服务公司 什么叫服务器管理器 计算机软件开发实习生工资 数据库开发要学的技术 泰格网络技术有限公司 领英服务器在美国 安全吗 塔科夫怎么开全球服务器 数据库可以装在移动硬盘里吗 数据库导论目录 好的服务器 思迅收银系统数据库在哪里 魅族 音乐 服务器超时 任丘盘古网络技术有限公司 人民医院网络安全 表格中自动填充特定的数据库 海南大学 网络安全 中国股票一级市场研究数据库 如何让孩子正确认识网络安全 CEIC全球经济数据库怎样进入 软件数据库怎么设置权限
0