3. RDMA技术基础:RDMA概述、InfiniBand与RoCEv2对比、RDMA内存注册、RDMA数据传输操作

各位同学,咱们今天聊点硬核的——RDMA。说实话,我在做NVMe over Fabrics之前,对RDMA的理解也停留在“知道它很快”这个层面。直到第一次在数据中心里调优存储性能,被网络延迟折磨得够呛,才真正意识到RDMA这东西有多重要。

RDMA,全称是Remote Direct Memory Access。说白了,就是让一台机器的网卡,能直接读写另一台机器的内存。不需要经过CPU,不需要经过操作系统协议栈。你想想看,传统网络通信,数据要从应用层一路拷贝到内核,再经过TCP/IP层层封装,最后才到网卡。这一路下来,延迟和CPU开销都很大。RDMA直接把这条路给抄了近道。

核心思想:RDMA让数据从一台机器的内存,直接传输到另一台机器的内存。中间不打扰CPU,不经过内核。

3.1 RDMA的三种实现方式

目前主流的RDMA技术,主要有三种:InfiniBand、RoCEv2和iWARP。我个人在实际项目中,主要接触前两种。iWARP用的场景相对少一些,咱们今天重点聊InfiniBand和RoCEv2。

  • InfiniBand:这是RDMA的“原配”。从硬件到协议,全部为RDMA设计。性能最好,但成本也最高。需要专用的IB交换机和HCA卡。
  • RoCEv2:全称RDMA over Converged Ethernet v2。它把RDMA跑在标准以太网上。成本低,部署灵活。但需要网络支持PFC(优先级流控制)等特性。
  • iWARP:基于TCP的RDMA。性能受限于TCP协议栈,延迟比前两者高。现在用得越来越少了。

3.2 InfiniBand vs RoCEv2:怎么选?

这个问题,几乎每个做NVMe over Fabrics的人都会问。我个人的经验是:没有的好坏,关键看你的场景和预算。

对比维度 InfiniBand RoCEv2
延迟 极低(<1μs) 低(1-3μs)
带宽 高(HDR 200Gbps+) 高(100G/200G以太网)
成本 高(专用硬件) 中等(标准以太网硬件)
部署复杂度 中等(独立网络) 较高(需调优以太网)
兼容性 仅IB设备 标准以太网设备
丢包处理 无损设计 依赖PFC/ECN

嗯,这里要注意。RoCEv2虽然成本低,但它对网络的要求其实挺苛刻的。我曾经在一个项目中,RoCEv2网络因为交换机缓存配置不当,导致大量丢包,性能直接掉到传统TCP的水平。后来花了整整两天调PFC参数才搞定。所以,如果你选RoCEv2,一定要确保你的网络设备支持并正确配置了无损以太网特性。

我的建议:如果预算充足,追求极致性能,选InfiniBand。如果希望复用现有以太网基础设施,控制成本,选RoCEv2。但别指望“插上就能用”,RoCEv2的调优工作不比InfiniBand少。

3.3 RDMA内存注册

RDMA要直接读写远程内存,那问题来了——网卡怎么知道哪些内存可以访问?总不能把整个物理内存都暴露出去吧?这就引出了RDMA内存注册的概念。

说白了,内存注册就是告诉RDMA网卡:“这块内存区域,你可以直接访问。” 注册之后,网卡会得到两个关键的东西:L_Key(本地密钥)和R_Key(远程密钥)。本地操作用L_Key,远程操作用R_Key。

我刚开始学的时候,总觉得这玩意儿有点多余。直到有一次,因为忘记注册内存,程序直接崩溃了。嗯,从那以后我再也不敢跳过这一步了。

// 伪代码示例:注册一块内存区域
struct ibv_pd *pd;          // 保护域
struct ibv_mr *mr;          // 内存区域
void *buf = malloc(4096);   // 分配4KB缓冲区

// 注册内存,获取L_Key和R_Key
mr = ibv_reg_mr(pd, buf, 4096, 
                IBV_ACCESS_LOCAL_WRITE | 
                IBV_ACCESS_REMOTE_WRITE);

// mr->lkey 和 mr->rkey 就是后续操作要用到的密钥
// 把rkey和远程地址告诉对端,对方就能直接写这块内存了

避坑指南:我曾经见过有人把R_Key直接硬编码在代码里,结果安全审计没过。R_Key相当于你内存的“钥匙”,一定要妥善管理。生产环境中,建议通过安全的密钥交换机制来传递。

3.4 RDMA数据传输操作

RDMA的数据传输,主要有两种操作模式:Send/Recv 和 Read/Write。这两种模式,说白了就是“主动推送”和“主动拉取”的区别。

3.4.1 Send/Recv:传统通信模式

这个模式跟TCP的send/recv有点像。A端发送数据,B端必须提前准备好接收缓冲区。如果B端没准备好,A端的数据就发不出去。这种模式适合控制消息、小数据量的场景。

  • Send:主动发送数据到对端
  • Recv:提前注册接收缓冲区,等待数据到来
  • 需要双方配合,类似“握手”

3.4.2 Read/Write:真正的RDMA精髓

这才是RDMA的杀手锏。A端可以直接读取B端的内存,或者直接写入B端的内存。B端的CPU完全不知道发生了什么。你想想看,这在存储场景下有多爽?NVMe over Fabrics的读写操作,底层就是靠RDMA Read/Write实现的。

  • RDMA Read:从远程内存读取数据到本地
  • RDMA Write:把本地数据写入远程内存
  • 不需要对端CPU参与,真正的“零拷贝”

关键区别:Send/Recv需要双方CPU参与协调,而Read/Write完全绕过对端CPU。这也是RDMA能实现超低延迟的根本原因。

3.5 本章知识体系总览

为了让大家更直观地理解RDMA的整个知识结构,我画了一张图。这张图把RDMA的核心概念、实现方式、内存管理和数据传输操作串在了一起。

RDMA技术基础 - 知识体系 RDMA概述 远程直接内存访问,绕过CPU和内核 InfiniBand RoCEv2 iWARP RDMA内存注册 ibv_reg_mr → 获取L_Key(本地密钥)和R_Key(远程密钥) Send / Recv 需双方CPU参与,类似握手 Read / Write 绕过对端CPU,零拷贝精髓 核心目标:降低延迟、减少CPU开销、实现高带宽数据传输

这张图把咱们今天讲的内容串起来了。从上到下,先理解RDMA是什么,再看三种实现方式怎么选,然后掌握内存注册这个基础操作,最后搞清楚数据传输的两种模式。嗯,有了这个框架,后续学习NVMe over Fabrics就会轻松很多。

实战小贴士:刚开始接触RDMA编程时,建议先用Send/Recv模式写一个简单的ping-pong程序。等理解了基本流程,再切换到Read/Write模式。我当年就是这么一步步过来的,踩的坑少很多。

好了,这一章的内容就到这里。RDMA是NVMe over Fabrics的基石,理解透了,后面的路就好走了。

可可精品资料库