前年我们把一批分布式训练任务的参数同步从 TCP 切换到 RDMA 之后,单次全量同步耗时直接从两秒左右降到了三百毫秒以内。当时多数人的第一反应是“这张网卡真快”,但真正负责底层网络的人心里都清楚,跑出这个数字的不只是网卡硬件,背后是一整套从驱动、固件、交换机配置到拥塞控制机制的协同工作。也是从那次开始,我在公司里的主要精力就放在了 RDMA 高性能网络的规划与实施上。
我在一线负责过多个云平台网络方案的落地,这篇博文想写的,正是一条完整的 RDMA 高性能网络在云平台上从选型到落地再到排障的过程。它不是厂商白皮书,也不是教科书,而是一个实际干过这摊活的人,把方案取舍、关键参数、配置细节和踩过的坑一次性讲清楚。适合正在做云平台网络、容器网络、高性能计算平台或者分布式训练基础架构的工程师参考,同时对刚接触 RDMA 的读者也比较友好,基础概念我会用白话解释。
1. 云平台高性能网络的方案选型:三条路线与一个选择
1.1 三条技术路线:InfiniBand、RoCEv2、iWARP
RDMA 不是单一技术,实际落地时有几条不同路线,方案组一开始就在这三者之间反复对比。
第一条是 InfiniBand。它是一套端到端的专用网络技术,链路层、网络层、传输层都有自己独立的定义,交换机也必须是专用设备。它的最大优势是天然无损:InfiniBand 用自己的 credit 流控机制保证缓存不会溢出,几乎不需要额外配置就能跑到很高的有效带宽,时延也是三者里最低的。缺点同样明显:专用交换机的采购成本明显高于以太网设备,而且它跟传统以太网的运维体系完全不互通,如果你想在同一个机房混布普通业务和高性能业务,就需要维护两套物理网络、两套监控、两套排障工具,这个隐性成本比设备差价还让人肉疼。
第二条就是 RoCEv2。RoCE 的全称是 RDMA over Converged Ethernet,v1 版本还只能跑在二层网络里,v2 版本把报文封装进 UDP,这样就能借助标准 IP 路由做三层组网,灵活性高了很多。但 RoCEv2 跑在普通以太网上,就需要让以太网具备“无损”能力——也就是后面重点要说的 ECN 和 PFC 机制。因为能复用现有的以太网交换机和网管体系,RoCEv2 是当前数据中心里最主流的选择,我们最终也选了它。
第三条是 iWARP。iWARP 直接基于 TCP,想利用 TCP 本身的可靠传输来做 RDMA。听起来很省事,但代价是硬件卸载复杂度高、性能很难跑上去,实际上只在一些历史遗留系统里还能见到。新建云平台真没必要再碰 iWARP。
我把这三条路线的关键差异整理成了一张表,方便对比:
| 技术路线 | 底层协议 | 依赖网络 | 成本 | 性能 | 生态 |
|---|---|---|---|---|---|
| InfiniBand | 自有协议栈 | 专用交换机 | 高 | 最高 | 传统 HPC 强 |
| RoCEv2 | UDP/IP | 无损以太网(ECN/PFC) | 中 | 高 | 最广 |
| iWARP | TCP/IP | 普通以太网 | 低 | 一般 | 几乎停滞 |
1.2 为什么最终选了 RoCEv2
选择 RoCEv2 不是因为它每一项指标都最强,而是它在我们的约束条件下的综合得分最高。
首先,成本与带宽的平衡。100G/200G 的以太网硬件已经非常成熟,采购渠道多、价格稳定。同等数量的节点,RoCEv2 的资金投入比 InfiniBand 低不少,而性能差距在我们实际业务场景里没有那么大。
第二个原因是能复用现有网络运维体系。RoCEv2 在三层走标准 IP,意味着现成的路由、VLAN、子网划分、监控告警都可以继续用。云平台本来就有一套复杂的网络管理体系,再引入一套专用网络格式,运维团队的负担会成倍增加。
第三个原因是生态兼容性。AI 训练框架里的集合通信库、分布式存储里的 NVMe over Fabric、各类高性能中间件,几乎都优先支持 RoCEv2,遇到问题能查到的资料也多。InfiniBand 在传统 HPC 里很强,但在我们这种混合负载的云平台上,RoCEv2 的兼容面要宽得多。
最后也是最重要的,性能达标。在配置正确的前提下,RoCEv2 能跑到线速的 95% 以上,时延在 0.7 到 1.2 微秒这个区间,完全满足我们训练任务和存储业务的诉求。所以我的结论是,选择方案时最怕的不是技术不行,而是运维体系被割裂成两套,那才是真正让团队崩溃的事情。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 虚拟化与容器场景的 RDMA 接入方式
定了 RoCEv2 之后,更大的问题来了:云平台是虚拟化环境,用户需要“按需创建一个实例,这个实例自带 RDMA 高速通路”。物理机上跑 RDMA 很简单,但引入虚拟化层之后,网卡设备怎么分、怎么隔离、性能损耗多少,每一个问题都要单独评估。
2.1 物理机直连与 PCIe 直通的适用边界
先看最简单的方案:物理机直连。也就是把 RDMA 网卡直接插在物理机上,不经过任何虚拟化层,业务以裸金属形式运行。这种方式性能最稳、配置最简单,适合计算密集型的裸金属池,或者专门划出来的高性能分区。但它的缺点也很明显:灵活性差,没法按需动态伸缩,用户想要一个环境就得重新分配物理机。
再往前走一步是 PCIe 直通(Passthrough),也就是把整块物理网卡直接挂给一台虚拟机。虚拟机里看到的是一块完整物理网卡,功能没有任何裁剪,性能跟物理机几乎没差别。问题在于,一块网卡只能给一台虚拟机,100G 网卡按单块成本算,分配给单个业务实例太奢侈。而且这种虚机基本不能做热迁移,调度上会受到很多限制。
所以我们的判断是:直通和裸金属适合高性能计算里的少数重量级业务,但不适合云平台大规模铺开。真正扛大头的,得是 SR-IOV。
2.2 SR-IOV:一台宿主机跑多个 RDMA 实例
SR-IOV 的核心思路是,物理网卡通过一个物理功能(PF)创建出多个虚拟功能(VF),每个 VF 独立拥有一组队列和中断能力,可以被单独分配给一台虚拟机。这样一来,一块 100G 网卡就能拆出几十个 VF,分配给多台虚机,资源利用率一下子拉起来了。我们内部大多数 RDMA 虚机都是走这条路径。
使用 SR-IOV 前,需要在宿主机 BIOS 里开启 SR-IOV 和 IOMMU,然后在系统里创建 VF。创建 VF 的核心命令其实很简单:
bash复制echo 16 > /sys/class/net/<网卡名>/device/sriov_numvfs
这里的 16 就是你要创建的 VF 数量,具体上限取决于网卡型号和固件。创建完可以用 ip link show 检查 VF 是否出现,再把它通过虚拟化平台的管理接口分配给虚机。
SR-IOV 用起来方便,但有几个坑必须提前知道。
第一,VF 之间的隔离不是绝对的。PFC 的暂停机制是物理端口级的,如果某个 VF 流量突发,导致整个物理端口产生 pause 帧,那么同端口下的其他 VF 也会受影响。也就是说,你在宿主机上做了一个“坏邻居”,整块网卡上的虚机都可能跟着遭殃。
第二,VF 数量增加之后,默认队列数、中断数都得跟着调,否则性能上不去。
第三,热迁移基本不可用。使用 VF 的虚机,live migration 是受限的,这是硬件直通类方案的通病。在云平台设计上,这种虚机要么打上“禁止迁移”标签,要么上层调度时尽量避免跨宿主机迁移。
2.3 容器场景下 RDMA 的接入要点
现在我们的很多业务以容器方式跑在容器编排平台上,容器的 RDMA 接入和虚机又不一样。容器本质是共享宿主机内核的进程,设备隔离比虚机更薄。
容器接入 RDMA 的常见路径是:通过容器平台的设备插件机制,把 RDMA 设备或者对应的设备文件暴露给容器,再配合 CNI 插件完成网络配置,给容器分配 IP 和 VLAN,并在容器内通过 verbs 接口直接访问网卡。
这里有一个容易踩的坑:容器内的内存锁限制。RDMA 做内存注册的时候会把内存锁定住,默认的 memlock 限制很小,一调高带宽就报错。我们需要在容器运行时层面把这个限制调大,否则第一轮压测就会翻车。另外网卡对应的设备文件必须正确挂载进容器,很多“驱动装了但 verbs 调用失败”的问题,其实就是容器里根本看不到那个设备文件。
3. 让 RDMA 网络“不崩”的关键机制:ECN 与 PFC
说完了接入方式,必须聊聊让 RDMA 真正可用的底层机制。这是整篇文章我觉得最重要的部分,因为很多团队跑 RDMA 跑不起来,问题都出在这里。
3.1 先回答一个基本问题:RDMA 为什么怕丢包
普通以太网应用跑 TCP,丢包不是世界末日。TCP 有滑动窗口、有重传,丢包时带宽下降一些,但业务基本还能撑住。
RDMA 就不一样。虽然 RC 可靠连接模式也提供重传,但重传代价极其高昂,涉及硬件重发整个工作请求、CPU 处理大量完成队列事件,一旦丢包率上来,性能就会断崖式下跌。业内大致有这样一个经验值:RoCEv2 网络里丢包率超过 0.1%,有效带宽可能掉到原来的十分之一以下,RDMA 的优势基本归零。
所以在 RoCEv2 网络里,大家追求的是“尽量不丢包”。于是就有了无损网络的概念,而无损网络的实现主要靠两招:ECN 和 PFC。简单说,ECN 是让发送方在拥塞发生早期主动降速,PFC 是当队列真的快溢出时,用暂停帧强制对端停手。
3.2 DCQCN:让发送方主动降速的拥塞控制
先讲 ECN 这条线。RoCEv2 网络里最常用的拥塞控制方案叫 DCQCN,整个过程可以拆成四步。
第一步,交换机持续监控队列长度。当队列占用超过设定的 ECN 标记阈值时,就对经过的 RoCEv2 报文打上 ECN 标记。
第二步,接收方收到带标记的报文后,会生成一个 CNP 拥塞通知报文,回传给发送方。
第三步,发送方收到 CNP 后,按照乘性减小的策略调整发送速率,通常是直接减半,然后再通过字节计数器和定时器慢慢恢复速率。
第四步,整个流程全部在硬件里完成,CPU 基本无感知。
用生活里的例子来类比:ECN 就像高速匝道口的探头,车流密度超过阈值的时候,电子提示牌通知后面的车限速,避免整条路堵死。这里的探头和提示牌就是 ECN,传送限速指令的信使就是 CNP,车辆看到限速牌之后踩刹车,就是发送方的降速动作。
DCQCN 的配置里有几个关键参数,其中最核心的是 ECN 标记阈值。阈值设置太保守,发送方动不动就降速,带宽跑不上去;阈值设置太激进,标记发得太晚,队列可能已经溢出,PFC 就会频繁介入。我们一般把出口队列的 ECN 标记阈值放在 buffer 水线的一半左右,然后通过压测微调。这个“微调”是很有讲究的,不是拍脑袋,需要观察 ECN 标记计数和 pause 帧计数的比例关系来逐步逼近最优值。
3.3 PFC:无损队列的恩赐与陷阱
再讲 PFC 这条线。PFC 基于 802.1Qbb 标准,作用是按优先级做流量控制。当某个优先级队列的 buffer 快满时,下游端口会向上游端口发送 pause 帧,暂停对端继续发送这个优先级的流量,直到 buffer 恢复。
我们可以把 PFC 理解为 ECN 的最后一道保险:ECN 让发送方减速,但减速需要时间,如果瞬时突发太大,队列还是可能溢出,这时 PFC 用暂停帧把压力往上游推,硬生生保住不丢包。
但 PFC 是一把双刃剑,用不好就是事故源头。它的副作用主要有两个。
第一个是队头阻塞。PFC 虽然按优先级队列独立工作,但交换机的内部 buffer 和调度资源经常是共享的,一个优先级被暂停,同端口的其他优先级流量也会在排队上受影响,时延会明显变大。
第二个更严重,叫 PFC 死锁。当多个端口之间形成暂停帧的循环等待时,整个网络相当于进入一种活锁状态,性能会归零,而且很难自动恢复。这是无丢包网络最被诟病的地方。
所以配置 PFC 有一条红线:只给真正需要无损的流量开 PFC,比如给 RDMA 流量指定一个独立优先级,通常用 COS 3,其他流量全部走 lossy 队列。绝对不要图省事,把所有优先级都开 PFC,否则一个端口拥塞就可能引发整片网络的连锁暂停。
4. 从零搭建 RDMA 高性能网络的完整实操记录
接下来是实操部分。我会把我们搭建过程中每一步的关键动作和参数整理出来,尽量做到可以直接照着操作。
4.1 硬件与前置检查清单
动手之前,先把硬件底子确认清楚,否则后面全是白费功夫。
第一,网卡必须支持 RoCEv2。我们用的是某主流厂商的 100G/200G 网卡,注意不是所有高速网卡都支持 RDMA。采购阶段就要确认网卡规格表里明确写了 RoCE、RDMA 字样。
第二,BIOS 设置。需要开启 SR-IOV,开启 IOMMU/VT-d,如果平台用 PCIe 直通,还要确认 ACS 支持。这些设置漏掉一个,后面创建 VF 或者直通的时候就会出现一些莫名其妙的问题。
第三,交换机能力。必须支持无损队列、ECN、PFC、DCBX。确认交换机固件版本太老,很可能连 ECN 标记都不会打。我们曾经遇到一台“支持 ECN”的交换机,实际行为却像没开一样,排到最后发现是固件 bug,升级才解决。
第四,拓扑规划。计算节点与存储节点之间的链路带宽、收敛比要先算清楚。核心链路上至少要 1:1 收敛,如果上联带宽不足,拥塞点必然出现在上联口,什么拥塞控制都救不回来。
4.2 驱动安装与固件升级
驱动版本选型这块,我踩过的坑比较多。总原则是:安装厂商官方 OFED 驱动,版本和内核版本强相关,不是越新越好,但也不能选太旧的,最好选在各家云厂商大规模验证过的长期稳定版本。
装好驱动之后,用下面几条命令做基础验证:
bash复制ibv_devinfo
ibstat
rdma link show
ibv_devinfo 能看到设备属性和端口状态,确认 link 是 active;ibstat 可以看物理端口状态;rdma link show 更偏内核层面的链路信息。这三条命令跑完,基本能确定驱动加载是否正常。
特别提醒,驱动和固件要一起看。我们在压测中遇到过“安装完驱动后性能只有预期一半”的怪现象,查到最后是网卡固件太旧,和对端交换机固件不匹配,协商出来的链路能力不对。更新固件后问题立马消失。所以固件尽量在用大规模部署前统一更新一遍,避免新旧固件混合跑。
4.3 QoS 参数配置
QoS 配置的最终目标,是让 RDMA 流量走无损队列,同时让 ECN 生效。核心其实就是确认三个映射关系:
- 流量优先级(PCP/DSCP)到 TC(Traffic Class)的映射;
- TC 到队列的映射;
- 队列的丢包策略是 lossless 还是 lossy。
具体操作上,先把 RDMA 流量的 DSCP/PCP 固定到一个优先级,比如统一到 COS 3,然后在交换机侧把优先级 3 对应的队列配置为无损队列,开启 PFC,并在这个队列上设置 ECN 阈值。其他流量映射到 lossy 队列,保持传统以太网行为。
这里有一个非常隐蔽的坑:交换机侧和网卡侧的优先级映射必须完全一致。我们曾经有一个机柜的 RDMA 性能只有其他机柜的一半,排查了很久,最后发现是机柜对应的两台交换机漏配了 DCBX 的优先级映射,导致网卡认为流量在无损队列,交换机却把它当成普通流量处理,PFC 和 ECN 全都没生效。这类配置漂移问题在规模不大时很难发现,只有跑到多机柜对比测试才会暴露。
4.4 性能验证:带宽和时延到底怎么测
配置完成后,不要急着上业务,先做一轮认真的性能验证。
单链路基础测试用 perftest 工具集:
bash复制ib_write_bw -d <设备名> --report_gbits
ib_read_lat -d <设备名> -a
多流测试可以加并发数:
bash复制ib_write_bw -d <设备名> --report_gbits -n 8
有几个测试细节我要单独强调。
第一,单条流测试值只能反映最理想情况,真实业务里并发流很多,一定要测多流并发。第二,测试前把 CPU 频率自动调节关掉,绑定到固定核心,否则时延抖动的结果会让人误判网络有问题。第三,测试进程要离开网卡对应的 NUMA 节点太远,跨 NUMA 访问内存会导致时延异常。
以我们线上 100G 环境为例,ib_write_bw 实测单链路能到 97Gbps 左右,多流场景保持 96Gbps,时延在 0.8 到 1.2 微秒。如果带宽明显低于 90Gbps,优先检查 EC N 阈值是不是设得太保守,再看驱动有没有开启硬件卸载。
5. 线上高频问题与排查实录
方案落地后,真正考验人的是线上问题排查。这一章我整理了一些高频问题和两个典型案例。
5.1 高频故障速查表
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| 带宽起不来 | ECN 阈值过高/过低、驱动太旧、MTU 不一致 | 调 ECN 水线、升级驱动、统一 MTU |
| 时延周期性飙高 | PFC 风暴、pause 帧触发频繁 | 查 pause 计数,定位风暴源头 |
| 虚机 RDMA 不稳定 | VF 队列数不足、中断没绑核 | 调整 VF 配置,IRQ 绑定非业务核心 |
| 容器内 verbs 调用失败 | memlock 限制、设备文件未挂载 | 调大 ulimit -l,检查设备挂载 |
这张表是排查的起点,实际定位过程往往要结合计数器和监控一起看。
5.2 一次 PFC 风暴的完整定位过程
这里分享一个真实的排查过程。我们在 64 节点压测时发现,整体带宽每隔几十秒就会掉到正常值一半左右,持续几秒后自动恢复,非常规律,就像什么定时任务在捣乱。
第一步,检查每台节点和交换机的 pause 帧计数。我们用 ethtool -S <网卡名> | grep pause 把所有节点的收发 pause 帧统计抓出来,发现某个机柜上联口的 rx_pause 帧数量异常高。
第二步,顺着 pause 链路向上游回推。这个机柜的上联口连接的是同一批训练任务的计算节点,而这些节点的流量汇聚到上联口时形成了典型的 incast 流量,也就是多打一。
第三步,再看 ECN 标记计数。发现这台交换机的出口队列频繁触发 ECN,但同时 PFC 也在高频触发。这说明 ECN 阈值设得偏高,标记来不及起作用,队列就满了,最终只能靠 PFC 兜底。
第四步,把这个级联口的 ECN 标记阈值下调,让拥塞控制更早介入,同时优化了降速恢复参数。PFC 的 pause 帧计数明显下降,带宽曲线恢复了平稳。
这次排障让我形成了一个判断原则:PFC 不是不能触发,但绝对不能成为常态。如果 PFC 频繁触发,说明前面的 ECN 没有当好第一道防线,优先调整 ECN 而不是加大 PFC 的 buffer,方向才对。
5.3 一个虚拟化场景的 CPU 飙升排查
另一个典型案例,是宿主机开启 SR-IOV 后,一台物理机上跑了 8 台带 RDMA 的虚拟机,宿主机 CPU 的 softirq 占用突然飙到 30% 以上,虚拟机的网络性能也忽高忽低。
一开始以为是设备分配问题,后来用 mpstat 观察,发现 softirq 全都压在一个 CPU 核心上,而系统默认中断亲和性没有设置,所有网卡中断都落在了 CPU0。
进一步排查发现,这个 CPU0 恰好又是某台高吞吐虚拟机 vCPU 所在的核心。两边抢一个核,延迟抖动自然就上来了。
解决办法是手动把 RDMA 网卡的各队列中断重新绑定到非业务计算核心,或者配置好中断负载均衡服务,让它避开核心业务线程。操作完成之后,宿主机 softirq 占用明显降下来,虚拟机的读写时延抖动也恢复了。
这里还有个细节容易被忽略:绑核时一定要避开 NUMA 跨节点,否则中断处理程序访问远端内存的代价,比中断共享还严重。很多人绑核后性能反而更差,大概率就是绑到了远端 NUMA 的核心上。
6. 这几个经验,值得一次通宵来换
整套 RDMA 高性能网络从方案设计到线上平稳运行,我自己总结下来有几点体会。
如果你只是小规模试点,可以先从物理机加静态配置跑起来,把单链路性能调优、拥塞事件仿真、多机压测这条链路走通,再扩大规模。直接上大规模虚拟化环境,出了问题很难分清是配置问题还是架构问题。
建议把所有网卡和交换机上的 pause 帧计数、ECN 标记计数都纳入监控大盘。在无损网络里,这些计数的异常波动比丢包率更有预警价值。PFC 和 ECN 行为的变化,往往意味着拥塞控制机制正在提前失效,等业务侧感受到性能下降再排查,就晚了。
最后再分享一个小技巧:新接入一批 RDMA 节点后,花一天时间专门做一次跨机柜的并发压测,人为制造 incast 流量,看看 PFC 和 ECN 是否各司其职。很多配置漂移问题,就是在这类“找茬式压测”里被提前暴露出来的。与其在线上故障时手忙脚乱,不如先让自己在测试环境里难受一天。
