2、RDMA技术基础:RDMA原理、三种实现方式对比、零拷贝技术

2.1 为什么需要RDMA?——传统网络的痛点

聊RDMA之前,我先说说传统网络的问题。你想想看,一次普通的数据传输,数据要从应用缓冲区拷贝到内核缓冲区,再经过协议栈层层封装,最后通过网卡发出去。接收端呢?反过来再来一遍。这中间有多少次内存拷贝?我数过,至少4次。

更麻烦的是,每次拷贝都需要CPU参与。CPU本来应该干正事的——比如跑你的数据库查询、处理你的AI模型——结果呢?它忙着把数据从A搬到B。这就像让一个顶级外科医生去干搬运工的活,浪费啊。

我早年做存储系统时,遇到过一台服务器CPU跑到100%,结果一看,一半以上的资源都花在网络数据拷贝上。那时候我就想,一定有更好的办法。

2.2 RDMA的核心原理——绕过内核,直接访问

RDMA的全称是Remote Direct Memory Access,远程直接内存访问。说白了,就是让一台机器的应用可以直接读写另一台机器的内存,中间不需要经过操作系统内核。

怎么做到的呢?核心就三点:

  • 内核旁路(Kernel Bypass):应用直接与网卡硬件通信,不经过内核协议栈。数据从用户态直接到网卡,再从网卡直接到用户态。
  • 零拷贝(Zero-Copy):数据不需要在应用缓冲区和内核缓冲区之间来回拷贝。网卡直接把数据放到应用指定的内存位置。
  • CPU卸载(CPU Offload):数据传输的整个流程由网卡硬件完成,CPU只需要在开始和结束时做少量工作。

我习惯用一个比喻来解释:传统网络就像你寄快递,要填单子、打包、叫快递员、送到中转站……而RDMA就像你直接把东西从窗口递到邻居手里,中间省掉了所有环节。

RDMA的核心价值:延迟从毫秒级降到微秒级,吞吐量提升数倍,CPU占用率大幅降低。

下面这张图展示了RDMA与传统网络在数据路径上的本质区别:

传统网络 vs RDMA 数据路径对比 传统网络(4次拷贝) 应用缓冲区 内核缓冲区 协议栈处理 网卡硬件 CPU参与 CPU参与 CPU参与 RDMA(0次拷贝) 应用缓冲区 网卡硬件 直接访问 硬件处理 绕过内核

2.3 三种实现方式对比

RDMA不是一种具体技术,而是一类技术的统称。目前主流的有三种实现:InfiniBand、iWARP和RoCE。我一个个说。

2.3.1 InfiniBand——原生RDMA,性能王者

InfiniBand是RDMA的"原配"。它从设计之初就是为高性能计算打造的,链路层、网络层、传输层全部原生支持RDMA。说白了,它是一套完整的"高铁系统",从轨道到列车到调度,全是专用的。

优点很明显:性能最好,延迟最低,生态最成熟。缺点呢?贵。你需要买专用的InfiniBand交换机、专用网卡、专用线缆。我记得2018年做一个HPC集群项目,客户一听InfiniBand交换机的报价,脸都绿了。

2.3.2 iWARP——在TCP上跑RDMA

iWARP的思路是:既然TCP/IP这么普及,能不能在上面跑RDMA?于是它把RDMA的传输层功能映射到TCP上。好处是你不需要换网络设备,现有的以太网交换机就能用。

但问题也出在这里。TCP协议栈本身有开销,而且iWARP需要硬件卸载才能发挥性能。我测试过纯软件实现的iWARP,延迟比InfiniBand高一个数量级。所以iWARP的市场一直不温不火。

2.3.3 RoCE——以太网上的RDMA,后起之秀

RoCE(RDMA over Converged Ethernet)是目前最火的方案。它把RDMA跑在以太网上,但不需要TCP/IP那套东西,而是直接在以太网帧里封装RDMA数据。

RoCE有两个版本:

  • RoCE v1:工作在同一个广播域内,不能跨网段。说白了就是只能在二层网络里用。
  • RoCE v2:引入了UDP头,可以路由了。这是目前的主流版本。

RoCE最大的优势是成本低。你不需要买专用设备,只要网卡支持RoCE,交换机支持无损以太网(PFC、ECN等),就能跑。我在项目中用RoCE v2做过NVMe over Fabrics,效果相当不错。

我的建议:如果是新建数据中心,预算充足,上InfiniBand。如果是改造现有网络,RoCE v2是最务实的选择。iWARP嘛……除非你有特殊的TCP兼容需求,否则不太推荐。

2.3.4 三种方式对比表

特性 InfiniBand iWARP RoCE v2
传输层 原生IB TCP UDP
延迟 最低(<1μs) 较高(~10μs) 低(1-3μs)
吞吐量 最高 中等
成本
兼容性 专用设备 标准以太网 无损以太网
生态成熟度 最成熟 一般 快速发展

2.4 零拷贝技术——RDMA的基石

零拷贝是RDMA最核心的机制。没有零拷贝,RDMA的性能优势就无从谈起。

传统的数据传输,数据要经过"磁盘→内核缓冲区→用户缓冲区→内核缓冲区→网卡"这条路径。每次拷贝都消耗CPU周期和内存带宽。零拷贝的目标就是消除这些不必要的拷贝。

RDMA的零拷贝是怎么实现的?关键在于两点:

  1. 注册内存区域:应用告诉网卡:"这块内存是我的,你可以直接读写。"网卡会记录这块内存的物理地址。
  2. 硬件DMA:数据传输时,网卡直接通过DMA引擎读写应用的内存,CPU完全不用管。

我曾经遇到过一个坑:有同事在代码里频繁注册/注销内存区域,结果性能反而比传统网络还差。为什么?因为注册内存区域本身有开销,需要建立页表映射、锁定内存页。正确的做法是:在初始化时一次性注册好,运行时复用。

注意:零拷贝不等于"不拷贝"。数据从网卡到应用内存的DMA传输本质上也是一次拷贝。但这次拷贝由硬件完成,不占用CPU,而且省掉了内核态和用户态之间的多次拷贝。这才是关键。

2.5 RDMA的三种通信模式

RDMA提供了三种基本的通信模式,我简单介绍一下:

  • SEND/RECV:类似传统的收发消息。发送方主动发数据,接收方需要提前准备好接收缓冲区。这是最常用的模式。
  • RDMA READ:读取方主动从远程内存读数据。远程机器不需要参与,数据直接写入本地缓冲区。
  • RDMA WRITE:写入方主动往远程内存写数据。同样,远程机器不需要参与。

RDMA READ和WRITE是真正的"远程直接内存访问",不需要远程CPU介入。我在做分布式存储时,就用RDMA WRITE来实现数据副本的写入,性能提升非常明显。

2.6 小结

RDMA的核心思想就八个字:绕过内核,硬件卸载。三种实现方式各有优劣,我个人最看好RoCE v2,因为它兼顾了性能和成本。零拷贝技术是RDMA的根基,理解它才能用好RDMA。

嗯,这一章的内容就到这里。下一章我们会深入RDMA的编程接口,看看怎么用代码把今天讲的理论落地。


专注资料整理