RDMA技术详解:从内存搬运到AI集群网络优化
2026/9/15 2:04:16 网站建设 项目流程

RDMA 这个缩写,前些年还只是存储和超算圈子里的“黑话”,这两年随着 AI 大模型把算力集群的规模推向新高度,它已经成了高性能网络领域躲不开的关键词。很多人第一次接触 RDMA,是从“它能省 CPU”“它很擅长搬数据”这类结论开始的,但真要问一句它到底怎么工作的、为什么能这么快,能讲清楚的人就没那么多了。

这篇文章我打算从最底层的内存搬运讲起,一路看到 RDMA 在 AI 集群网络里的落地形态。不堆术语,尽量用大白话把几条核心链路拆开。如果你正准备做分布式训练的网络调优,或者只是好奇“GPU 直连存储”这类宣传语背后的原理,这篇文章应该能给你一张比较完整的地图。咱们先从一个最原始的问题出发:为什么传统网络传输,怎么优化都觉得“重”?

1. 先理解内存搬运这件事为什么成了瓶颈

1.1 传统网络传输里 CPU 被“杂活”拖垮的真相

一台服务器要把数据发给另一台服务器,表面上是“网卡把数据发出去”,实际上数据不会自己跑到网卡里。应用程序先要把数据从用户态内存拷贝到内核态的内存缓冲区,再经过协议栈层层处理,最后才交给网卡。这个过程里,数据至少被完整拷贝了两次,甚至四次。CPU 不只是负责发起拷贝,它还得为每一个数据包计算校验和、组装协议头、处理中断,这些工作单个看都不重,但架不住量太大。

我举个直观点的数字:一个 100Gbps 的网卡,每秒钟能接收大约 1.48 亿个最小尺寸的数据包。就算每个包只消耗几千个 CPU 周期来处理,这个开销也足以把一个高端服务器 CPU 的所有核心全部吃满。换句话说,传统网络模式下,CPU 不是在“做计算”,而是在“当搬运工”,搬运本身的成本甚至超过了计算本身。这种模式在普通 Web 服务里勉强能忍,但在存储集群、分布式数据库、AI 训练这类场景里,纯粹是浪费算力资源。

1.2 DMA 是第一步,但不是终点

为了解决 CPU 搬运数据效率低的问题,工程师们很早就搞出了 DMA(Direct Memory Access)技术。DMA 允许外设直接读写系统内存,CPU 只需要在传输开始前配置好“从哪里搬、搬多少、搬到哪”,然后就能撒手不管,等 DMA 控制器做完再发个中断通知一声。

这个设计确实大大解放了 CPU,但注意,它只是在单台机器内部解决了问题。数据从网卡到内存这一段虽然不用 CPU 了,可数据从应用程序内存到内核缓冲区、再一路走到网卡的完整链路里,DMA 只能覆盖最后那一小段。真正让 CPU 疲惫的,是数据在不同缓冲区之间反复拷贝、以及协议栈处理的整个过程。光有 DMA,救不了整个网络传输路径。

2. RDMA 的核心思路:把“搬运”这件事整体外包

2.1 内核旁路与零拷贝:跳过“中间商”的数据通道

RDMA(Remote Direct Memory Access,远程直接内存访问)的思路和 DMA 一脉相承,但它的野心更大:不仅让网卡直接访问本机内存,还要直接访问远程机器的内存。实现这个目标靠两板斧。

第一板斧是内核旁路(Kernel Bypass)。传统网络里数据必须经过内核协议栈,而 RDMA 允许应用程序直接跟网卡交互,数据根本不进内核。应用程序在用户态直接注册一块内存区域,把这块区域的地址信息告诉网卡,网卡就能自行读写这块内存。这个操作绕开了内核,也绕开了内核协议栈的那些协议解析、缓存管理、锁竞争。

第二板斧是零拷贝。数据从源端应用程序内存到目的端应用程序内存,整个过程不经过任何中间缓冲区,没有多余的 CPU 拷贝,也不需要 CPU 参与逻辑控制。打个比方,传统网络相当于你叫了个快递员到家里取件,快递员先到小区驿站、再送到城市分拨中心、最后才送到收件人手上,每个环节都要有人扫码登记;RDMA 相当于给了快递员一把钥匙,他直接进你家拿走东西、直接开到对方家楼下放进去,全程只有一个动作。

2.2 从 IB 到 RoCEv2:三种 RDMA 实现路径的取舍

RDMA 不是一个具体的产品,而是一类技术的统称。当前主要有三条实现路线,工程上需要根据已有基础设施做选择。

  • InfiniBand(IB):从硬件到协议完全为 RDMA 设计,性能最好,端到端延迟可以做到亚微秒级,但需要专有的交换机、网卡和线缆,价格也最昂贵。传统 HPC 超算中心用得最多。
  • RoCEv2(RDMA over Converged Ethernet version 2):把 RDMA 报文封装在以太网帧里传输,可以复用现有以太网交换机。成本比 IB 低很多,但这要求网络不能丢包——因为 RDMA 协议对丢包极其敏感,一旦丢包,性能就会断崖式下跌,这也是为什么 RoCEv2 必须搭配无损以太网来用。
  • iWARP:把 RDMA 跑在 TCP/IP 协议栈上,兼容性最好,但性能受限于 TCP 的处理开销,实际场景中部署最少。

当前 AI 集群里最常见的选型是 RoCEv2。原因很直接:InfiniBand 性能虽好但产能有限、交付周期长、价格高;RoCEv2 在标准以太网硬件上就能实现接近 IB 的性能——前提是网络调优做到位。这也是为什么每次聊 AI 集群网络,RoCEv2 的 PFC、ECN 这些流控机制总是绕不开的话题。

2.3 Queue Pair 与 verbs 接口:数据搬运的“车间流水线”

RDMA 的编程模型里,最核心的抽象叫Queue Pair(QP)。每个 QP 由一对队列组成:一个发送队列(Send Queue)和一个接收队列(Receive Queue)。应用要发数据,就在发送队列里放一个工作请求(Work Request,WR),网卡会去执行这个请求,把指定内存里的数据发出去,完成后在完成队列(Completion Queue,CQ)里放一个完成通知。整个过程就是生产者-消费者模型:应用生产请求,网卡消费请求,再把结果回报回来。

QP 这个概念容易被新手忽略,但它恰恰是理解 RDMA 性能的关键。一个 QP 代表一条独立的通信上下文,多个 QP 之间可以并行处理互不干扰。比如一个应用要同时跟 8 台机器通信,可以建 8 个 QP,每个 QP 独立干活,网卡在多 QP 之间负载均衡。实际调优时,QP 的数量多少、每个 QP 的队列深度设置多少,直接决定能不能把网卡的并发能力吃满。这个我们到后面的配置章节再细说。

3. 从单机到集群:RDMA 的“内存”变成了整个集群

3.1 AI 集群里为什么需要 RDMA:数据喂不饱 GPU 的尴尬

搞 AI 训练的人应该都有这种体验:GPU 算力上去了,但训练效率提不上去,一看监控,GPU 有一大半时间在等数据。这就是典型的“数据饥渴”问题。分布式训练里,每个 GPU 卡既要读训练样本,又要跟其他节点上的 GPU 交换梯度,这两种流量加起来非常可观。

举个例子,一个千亿参数的大模型用 64 台 8 卡服务器做训练,每台服务器有 8 张 GPU,训练过程中每计算完一个 batch,就要做一次梯度同步。梯度数据量有多大呢?以千亿参数模型为例,梯度张量动辄几十 GB 甚至上百 GB。每轮迭代都要把这上百 GB 数据在集群里同步一遍,这还只是训练中的通信流量,数据读取的流量还没算进去。

如果用传统 TCP/IP 网络来做这种规模的梯度同步,每台服务器光是处理网络包就得消耗好几个 CPU 核心,而且是海量小包的 CPU 中断风暴,直接把训练节点打成“半瘫痪”状态。RDMA 的价值在这种场景下体现得最充分:它让数据在 GPU 显存之间直接流动,CPU 只做任务调度,不碰数据本身,GPU 收到的数据延迟低、吞吐高、对 CPU 的干扰小。

3.2 GPUDirect RDMA:数据直达显存,CPU 和主存彻底“出局”

AI 集群场景下,RDMA 还有一个进阶形态叫GPUDirect RDMA(简称 GDR)。常规 RDMA 是网卡直接访问主机内存(DRAM),但 GPU 的数据在显存(HBM)里,中间隔了一道 PCIe。如果网卡把数据先搬到主机内存,再由 CPU 发起拷贝把数据送进显存,这里又产生了一次额外拷贝和一次 PCIe 往返。

GPUDirect RDMA 的思路是:网卡绕过主机内存,通过 PCIe 直接读写 GPU 显存。数据从远端网卡出发,到达本地网卡之后,直接经 PCIe 写入 GPU 显存,整个过程不碰 CPU、不碰主机内存。这个能力对分布式训练意义重大,因为梯度同步的数据本来就是显存里的张量数据,如果每次同步都要先搬到主机内存再转一道,凭空多出的拷贝开销和延迟在千卡集群里会被放大到难以接受。

说个我调优时看到过的真实数字:在同样的集群里,开启 GPUDirect RDMA 之后,梯度同步的端到端延迟比“网卡先到内存、再拷贝到显存”的模式能降低 30% 以上。对那种每轮迭代通信时间占比很高的训练任务,这个优化可以直接换算成训练总耗时下降。

3.3 无损以太网:RoCEv2 离不开的“交通规则”

前面提过 RoCEv2 对丢包零容忍,这里展开讲一下为什么。RoCEv2 的数据传输依赖流控机制来保证不丢包,业界一般用PFC(Priority Flow Control,优先级流控)ECN(Explicit Congestion Notification,显式拥塞通知)两个机制配合。

PFC 的作用可以理解为“红绿灯”:当某个交换机端口快要拥堵时,它会向上一跳设备发送暂停帧,让上游设备暂时不要发数据,等自己处理完了再恢复。这就像是高速公路入口看到前方堵车,先放行一部分车,剩下的在匝道上等着。问题是,PFC 的作用范围是一个端口的所有流量,如果这个端口里同时混合了不同优先级的流量,暂停帧可能会误伤不该停的流量,引发队头阻塞。所以在部署 RoCEv2 时,通常会给 RDMA 流量打单独的优先级队列,跟普通 TCP 流量物理隔离。

ECN 则是“提前减速”的思路:交换机检测到拥塞时,不是在端口上直接暂停,而是在转发的包里打上拥塞标记,接收端看到标记后,会主动通知发送端降低发送速率。这个机制比 PFC 温和,也更精细,但需要端到端配合——网卡驱动、交换机、应用都要支持并正确配置。实际部署中,PFC 负责兜底防丢包,ECN 负责主动降速避免拥塞,两者配合才能让 RoCEv2 网络既无损又高效。

4. 动手配置一个 RDMA 环境的核心要点

4.1 硬件准备与驱动选型

搭建 RDMA 环境,首先得确认硬件是否支持。如果用 InfiniBand,必须买 Mellanox(现为 NVIDIA)或 Intel 的 IB 网卡和配套交换机;如果用 RoCEv2,还需要确认网卡型号支持 RDMA 功能。目前主流的高性能网卡,比如 NVIDIA ConnectX-6/7 系列、Broadcom 的一些网卡型号,都支持 RoCEv2。

驱动方面,NVIDIA 的网卡一般用 MLNX_OFED 驱动包,它集成了 RDMA 所需的 verbs 库、诊断工具和内核模块。安装驱动的时候有个小细节:必须确认系统内核版本和 OFED 版本的兼容性,网上很多 RDMA 起不来的案例,最后排查到底都是驱动和内核不匹配。装完驱动后,用ibv_devinfo命令能看到网卡的 RDMA 能力、支持的 MTU、端口状态,这是验证环境是否就绪的第一步。

4.2 子网管理器与链路确认

RDMA 环境里有个容易被忽略的组件叫Subnet Manager(SM,子网管理器)。在 InfiniBand 网络里,SM 负责为每个端口分配 LID(Local Identifier),也就是 IB 网络中的地址。没有 SM,IB 端口是起不来的。RoCEv2 因为是跑在以太网上,不需要 SM,但需要保证 IP 网络本身是通的、路由可及。

验证 RDMA 链路是否通,最常用的命令是ibping或者rping。我用得最多的是ib_write_bwib_read_bw这两个性能测试工具,它们能测出两个节点之间的实际读写带宽和延迟。第一次跑性能测试时,建议先跑一个小规模的带宽测试,比如两个节点之间的点对点测试,确认带宽能跑到线速的 80% 以上,再往下做多节点扩展测试。如果带宽明显偏低,优先级排查顺序是先看链路速率有没有协商到预期值,再看 MTU 设置是否一致,最后看流控配置是否生效。

4.3 QP 数量和队列深度的参数调整思路

很多人以为 RDMA 配置好驱动、网络通了就完事了,其实参数调优才是影响性能的关键。最重要的两个参数就是QP 数量和队列深度(Queue Depth)

QP 数量太少,多对通信会争抢同一个 QP,形成串行瓶颈;QP 数量太多,又会浪费网卡资源、增加管理开销。经验值是一个网卡上根据并发通信对的数量,每个通信对至少分配一个 QP,高并发场景可能一个通信对分配多个 QP 做并行。队列深度则是每个 QP 里能排队的工作请求数量,深度太小,应用生成请求的速度稍微一快,网卡就会空闲;深度太大,内存消耗增加而且延迟也会上升。一般建议从 128 开始测试,然后按 256、512 逐档往上调,观察带宽和延迟的曲线变化,找到拐点。

在 Mellanox 网卡上,这些参数可以通过mlx5_ib模块的 modprobe 参数或者ibv_create_qp接口在应用层指定。很多应用框架(比如 NCCL)本身暴露了环境变量来控制这些参数,NCCL 里就是通过NCCL_IB_QPS_PER_CONNECTION这个环境变量来调整每个连接的 QP 数量。实际训练任务里,QP 和队列深度没有万能设置,必须以实测为准,我见过太多照搬网上的“最优配置”,换了个集群规模后性能反而不如默认值的情况。

4.4 NCCL 与 RDMA 的经典配合

聊 AI 集群网络,NCCL(NVIDIA Collective Communications Library)是绕不开的名字。NCCL 是 NVIDIA 出的集合通信库,专门负责多 GPU 之间的数据交换,比如 AllReduce、AllGather 这类分布式训练里的高频操作。NCCL 的底层可以跑在多种传输方式上:共享内存、PCIe、以及 RDMA 网络。当节点数量超过一台机器时,NCCL 默认就会尝试用 RDMA 来做跨机通信。

NCCL 通过一系列环境变量控制 RDMA 的行为。最常用的是这几个:

  • NCCL_IB_DISABLE=0:显式启用 InfiniBand/RoCE 传输路径。
  • NCCL_IB_GID_INDEX:RoCEv2 环境下需要设置 GID 索引,尤其是在多网卡、多子网的复杂环境里,GID 索引选错会直接导致通信超时。
  • NCCL_IB_TIMEOUT:控制 IB 传输的超时时间,网络抖动大的场景需要把这个值调大,否则偶发拥塞会被误判为断连。
  • NCCL_IB_QPS_PER_CONNECTION:前面提到的 QP 数量控制。

实际训练中,NCCL 跑在 RoCEv2 上的常见故障就是“初始化超时”或者“连接断开”。排查这种问题,我一般分三步走:先确认所有节点到目标节点ping通且延迟正常;再确认 RoCE 的 GID 索引配置一致;最后用ib_write_bw在两个节点间做一次实测,看物理链路本身是否健康。链路没问题还超时,再怀疑 NCCL 参数和环境变量的问题。

5. 远端内存直接访问的排查利器与实战故障表

5.1 RDMA 故障排查的几个常用工具

RDMA 环境出问题的时候,光靠pingip a是不够的,需要专门的工具链。我常用的有这些:

  • ibv_devinfo:查看网卡的 RDMA 能力、端口状态、活跃速率、MTU 等基础信息。
  • ibstat/ibstatus:查看 InfiniBand 端口的链路状态、速率、宽度,确认是不是协商降级了。
  • ibping:IB 网络里的 ping,测试两个 IB 端口之间的连通性。
  • ib_write_bw/ib_read_bw/ib_send_bw:性能测试三件套,分别测写、读、发送三种操作的带宽和延迟。
  • perftest包的ib_*系列工具基本都在上述范围里,装完 MLNX_OFED 就会自带。
  • rdma_resource:查看系统中的 RDMA 资源使用情况,包括 QP、CM_ID、MR(内存区域)等,非常适合排查“QP 建不起来”“资源泄露”之类的问题。

用这些工具排查时,有个经验口诀:先看链路再看配置,先测点对点再测集群。很多问题单节点测试完全正常,一上集群就暴露,那是因为集群环境里多了交换机拓扑、多路径、拥塞等变量。

5.2 常见故障、原因与处置速查

故障现象可能原因排查思路与处置方法
ibv_devinfo显示端口状态为 DOWN线缆问题、对端设备未就绪、SM 异常(IB 场景)检查线缆和光模块是否正常,两端设备的端口状态是否协商成功。IB 场景检查 SM 是否在运行。
两个节点ping通,但ib_write_bw无法连接RoCEv2 的 GID 索引配置不一致,或者防火墙拦了 RDMA 端口对比两端的ibv_devinfo输出,确认 GID 索引一致;检查 iptables/firewalld 是否放行 RDMA 相关端口。
ib_write_bw带宽远低于预期MTU 不一致、PFC/ECN 未生效、链路协商降级、PCIe 带宽不足确认两端 MTU 一致且为最大值(通常 4096),检查交换机无损配置是否下发,用ibstatus确认链路速率,注意插在 PCIe 3.0 x8 上的 100G 网卡带宽本来就会被限制。
训练任务偶发超时,但点对点测试正常大规模集群下拥塞导致 RoCEv2 丢包检查 ECN 标记的计数器,确认交换机拥塞配置生效;加大NCCL_IB_TIMEOUT和重试次数;考虑调整拓扑减少多打一流量。
应用报错create QP failed内存注册不足、QP 数量到达硬件上限rdma_resource查看当前 QP 数量和使用情况;调整应用配置,减少并发 QP 数量;检查是否有旧的未释放的 QP 残留。
GPUDirect RDMA 没有生效,带宽没有提升驱动未开启 GDR 相关模块、BAR 映射失败检查驱动加载参数是否开启CONFIG_MLX5_VFIO等;用nvidia-smi topo -m确认 GPU 和网卡是否在同一 NUMA 节点或 PCIe switch 下。

这张表里的内容,都是我在实际部署和调优过程中反复踩过、也反复帮别人排过的坑。特别是 MTU 和 GID 索引这两个问题,几乎占了 RoCEv2 环境问题的半壁江山。

5.3 关于“内存”这件事的更深一层

最后聊一个容易被忽视的点:RDMA 之所以快,本质上是把“内存”这个资源的管理方式重构了。传统网络里,内存是被“拷贝”的,每经过一层就被复制一次;RDMA 里,内存是被“共享”的,网卡直接读远端用户态内存。这个思路落到底层,就是 RDMA 网卡需要维护一个内存翻译表,把应用注册的虚拟内存地址转换成物理地址,这就是注册内存区域(Memory Region,MR)这个操作的由来。

MR 注册是有代价的——注册 100MB 的内存区域,驱动要做页表锁定、地址映射,可能需要几十毫秒甚至更久。这也是为什么 RDMA 应用通常会复用注册好的内存缓冲区,而不是像 TCP 那样频繁分配释放。初次接触 RDMA 编程的人,最容易犯的错就是每个请求都重新注册内存,结果性能不但没提升,反而因为注册开销拖慢了速度。正确的做法是启动时一次性注册一块大的内存池,以后所有收发请求都从这个池子里分配缓冲区。

这个优化思路也解释了为什么很多高性能框架都要自己做内存池。它不只是为了减少 malloc 的开销,更深层的动机是避免频繁的 MR 注册和注销。内存分配的优化,到今天依然是 RDMA 场景里性价比最高的调优点之一。

6. 从网络到训练框架:一次性能调优的实战复盘

6.1 现象与目标

我之前帮一个团队做过一次 32 节点、256 卡集群的训练性能优化。训练任务用的是一套经典的 GPT 风格大模型,通信模式以 AllReduce 为主。跑起来之后发现,GPU 利用率只有 70% 左右,训练迭代时间波动也很大,每隔一段时间就会出现一次明显的长尾延迟。

第一反应是看网络。登录到计算节点,用ib_write_bw做了点对点测试,带宽正常,能达到 90Gbps以上。链路本身没问题,那就继续往前排查。接着看 NCCL 的通信日志,发现每次长尾延迟都伴随着 ECN 标记数量的激增,说明网络里确实有拥塞。进一步检查交换机的流控配置,发现虽然 PFC 是开启的,但优先级队列的映射关系没配置对——RDMA 流量和普通 TCP 流量被分到了同一个优先级,TCP 的突发流量直接把 RDMA 流量堵住了。

6.2 调整方案与效果

定位到问题后,调整了交换机上的优先级映射,把 RDMA 流量放到单独的优先级队列,并配置了严格的调度策略。同时,把 NCCL 的NCCL_IB_TIMEOUT从默认值调到更大,增加对偶发拥塞的容忍度。

调整之后的效果非常明显:迭代时间的长尾消失了,GPU 利用率从 70% 提升到了 92% 左右。整个训练任务的总耗时缩短了差不多 25%。这个案例让我印象很深,因为它说明了一个道理——RDMA 调优,很多问题都不在 RDMA 本身,而在它周边的生态配置。

6.3 这个事情还没完:RDMA 与 AI 网络的发展趋势

回过头来看,RDMA 在 AI 集群里的角色还在继续深化。一方面,随着模型参数规模持续膨胀,训练集群从千卡走向万卡,网络通信占比会越来越高,RDMA 几乎是唯一能撑住这种规模通信量的方案。另一方面,RDMA 也在和新的硬件形态融合,比如存算一体架构、CXL 内存池化这些新技术,本质上都在做同一件事——打破传统的数据搬运路径,让数据更直接地流向真正需要它的地方

我个人的体会是,懂 RDMA 的核心不在于记住几个命令和参数,而在于理解“数据从哪来、到哪去、中间能不能少绕几道弯”这条主线。内存搬运这件事听起来基础,却是整个高性能计算、存储和 AI 基础设施的共同底座。把这条线捋顺了,再去看 NCCL、看网络拓扑、看存储架构,整个视野都会不一样。

如果你正准备在自己的集群里部署 RDMA,我的建议是从小规模开始,两个节点先把链路调通、性能测达标,再逐步扩展到更多节点。不要一上来就照搬大规模配置,每个集群的拓扑、流量模型、硬件型号都不同,最可靠的方案永远是实测出来的那套

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询