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与传统网络在数据路径上的本质区别:
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的零拷贝是怎么实现的?关键在于两点:
- 注册内存区域:应用告诉网卡:"这块内存是我的,你可以直接读写。"网卡会记录这块内存的物理地址。
- 硬件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的编程接口,看看怎么用代码把今天讲的理论落地。