NNetpath
原理预计 30 分钟

为什么需要 RDMA:内核旁路与零拷贝

同样的 100Gbps 网卡,TCP 与 RDMA 的延迟差一个数量级。差在哪里,代价是什么。

学完这节你能做到

  • 说清 TCP 路径上哪几步被 RDMA 省掉了
  • 解释 QP、CQ、MR、Verbs 这几个基本概念
  • 判断一个业务该不该上 RDMA

建议先学跳过这几节会看不懂本节的部分推导

先算一笔 CPU 的账

100 Gbps 意味着每秒要搬 12.5 GB 数据。走标准 TCP 路径,每个包都要:

  • 至少一次内存拷贝(用户态 ↔ 内核态)
  • 一次协议栈处理(分段、校验、状态机)
  • 参与中断与软中断调度
  • 唤醒等待的进程,一次上下文切换

经验数据:内核 TCP 每 1 Gbps 大约要吃掉 1 GHz 左右的 CPU。跑满 100 Gbps 就是好几个核只用来搬数据, 而这些核本来该用于跑业务或者喂 GPU。

到了 400 Gbps 的量级,这条路直接走不通了。这才是 RDMA 存在的理由——不是"快一点", 而是在这个速率上,让 CPU 参与搬运本身已经不可行

RDMA 省掉了什么

路径推演一个包经过的每一跳

同一条物理链路,把内核整段摘出去之后剩下什么。

5延迟量级 个位数微秒
这条路径要记住的一句话

RDMA 快在省掉了协议栈、拷贝和上下文切换;代价是它假设网络不丢包,所以 PFC/ECN 必须配对。

对比两条路径,RDMA 省掉的正是 TCP 路径上最贵的三样:

省掉的东西TCP 路径上的代价
内存拷贝每个包至少一次拷贝,占内存带宽
内核协议栈分段、校验、状态机、netfilter
上下文切换系统调用 + 进程唤醒

剩下的路径极短:应用把请求写进队列 → 网卡自己 DMA 取数据 → 硬件封装发出 → 对端网卡直接落进内存。 全程 CPU 没有参与搬运。

延迟量级的差别:

路径典型单向延迟
内核 TCP(同机房)20–50 μs
RDMA(IB 或 RoCE)1–3 μs
i零拷贝与内核旁路是两件事
  • 内核旁路(kernel bypass):控制路径不走系统调用,用户态直接敲网卡的门铃寄存器
  • 零拷贝(zero copy):数据路径上网卡直接读写应用注册过的内存,不经过中转缓冲

两者都省,但省的是不同的开销。DPDK 只做到了内核旁路(数据仍要 CPU 轮询搬运), RDMA 两个都做到了 —— 这是它延迟能低到个位数微秒的原因。

五个基本对象

用 RDMA 之前必须认识这几个名词,后面所有报错都围绕它们:

对象全称是什么
QPQueue Pair一对发送/接收队列,相当于 RDMA 里的"连接"
CQCompletion Queue完成队列,操作干完了在这里通知你
MRMemory Region注册过的内存区域,网卡才有权限访问它
PDProtection Domain保护域,把一组 QP 和 MR 圈在一起做权限隔离
Verbs用户态 API(libibverbs),所有上层库都建在它上面

MR 是最容易出问题的一个。 注册内存意味着把它锁住(pinned),不允许被换出, 否则网卡拿着的物理地址就失效了。所以:

# 锁内存额度不足时应用会在初始化阶段就失败
ulimit -l            # 期望 unlimited

在容器里跑 RDMA 应用必须给 IPC_LOCK 能力,否则锁不了内存:

securityContext:
  capabilities:
    add: ["IPC_LOCK"]
×ulimit -l 和 IPC_LOCK 是新手第一道坎

症状是应用一启动就报 Cannot allocate memoryibv_reg_mr failed, 而机器上明明有大把空闲内存。原因是锁内存额度不够,不是内存不够。 容器里还要额外加 IPC_LOCK。这两件事查一次记一辈子。

单边操作:对端 CPU 完全不知情

这是 RDMA 最反直觉的地方:

类型操作对端 CPU 参与吗
双边SEND / RECV要,对端必须先挂好 RECV 请求
单边WRITE / READ不参与,网卡直接读写对端内存

WRITE 的含义是"我把数据直接写进你那块内存",对端应用毫不知情, 也不需要被中断打扰。这就是分布式存储和 AI 训练能榨出极限性能的关键: 接收方的 CPU 可以一直忙自己的事

代价是编程模型变了:双方要先交换内存地址和访问密钥(rkey), 谁在什么时候读写哪块内存都得由上层协议约定好。所以业务代码几乎不会直接写 Verbs, 而是用上层库:NCCL(AI 集合通信)、UCX、libfabric、NVMe-oF。

三种传输方式

方式底层说明
InfiniBand自己的二层三层链路层 credit 流控,天生无损;需要 SM 与专用交换机
RoCEv2UDP over IP能被普通三层网络路由;需要自己把网络配成无损
iWARPTCP靠 TCP 保证可靠,部署简单但生态小,实际很少见

现在的实际选择基本是前两个。它们的性能差距不大,差距在运维: IB 的无损是网络自带的,RoCE 的无损要靠人配 PFC 和 ECN——配错了比不配还糟。 下一节专门讲这件事。

代价清单

RDMA 不是免费的加速开关。上之前要认下面几笔账:

  • 网络必须无损(RoCE 场景):PFC / ECN 配错会全网卡顿,排查难度远高于 TCP
  • 排障工具全换一套tcpdump 抓不到 RDMA 的数据流(它绕过了内核), 要用 ibdumpperfquery、网卡计数器
  • 内存要注册、要锁住:容器里还要额外给权限
  • 应用要适配:不能靠改配置获得,得用支持 RDMA 的库
  • 硬件绑定:驱动(DOCA OFED)、固件、交换机版本要成套匹配
该不该上 RDMA:三个问题
  1. 业务在用支持 RDMA 的库吗(NCCL / MPI / NVMe-oF / GPFS)?如果应用只会用 socket,上了也用不到。
  2. 瓶颈真的是网络吗?先量一遍:如果 CPU 打满在业务逻辑上、或者磁盘先撞墙,网络换成 RDMA 也没用。
  3. 团队有人能调 PFC/ECN 吗(RoCE 场景)?没有的话,要么选 IB(网络自带无损), 要么先用高带宽 TCP 把业务跑起来。

AI 训练是唯一几乎不用犹豫的场景 —— 多机多卡的梯度同步就是纯粹的网络问题,NCCL 也天然支持。

检查点

检查点多选

RDMA 相比内核 TCP,主要省掉了哪些开销?(多选)

检查点单选

容器里的 RDMA 应用启动即报 ibv_reg_mr failed,但节点有大量空闲内存。最可能的原因?

检查点单选

关于 RDMA WRITE(单边操作),下面哪个说法正确?

这节课的落点

  • 内核 TCP 大约每 1 Gbps 吃 1 GHz CPU;到 400G 量级,让 CPU 搬数据这条路本身走不通
  • RDMA = 内核旁路 + 零拷贝,延迟从几十微秒降到个位数微秒
  • 五个基本对象:QP、CQ、MR、PD、Verbs;MR 必须锁内存,容器里要给 IPC_LOCK
  • 单边操作(WRITE/READ)对端 CPU 完全不参与,这是性能的关键来源
  • IB 天生无损,RoCEv2 要自己把以太网配成无损,性能接近但运维成本差很多
  • 上 RDMA 前先确认三件事:应用是否支持、瓶颈是否真在网络、团队能否调无损网络

延伸资料