2、RDMA基础概念:什么是RDMA、与传统TCP/IP网络的区别、关键术语(HCA、QP、CQ、MR、PD等)
RDMA(Remote Direct Memory Access,远程直接内存访问)是一种允许网卡直接读写远端主机内存,而无需双方操作系统内核参与数据搬运的网络通信技术。它并非一种全新的物理链路,而是一种重新定义“数据如何从应用内存到达对端应用内存”的协议栈与硬件协同架构。理解RDMA,首先需要建立与传统TCP/IP协议栈的对比视角,再逐步掌握其核心对象(QP、CQ、MR、PD)的职责与协作关系。本章将围绕“是什么、区别在哪、关键术语如何协同”三个层次展开,为后续章节的报文解析与调优打下基础。
2.1 核心原理:RDMA的本质是“内核旁路”与“硬件接管”
RDMA的核心思想可以概括为:让网络适配器(HCA)成为数据传输的主体,而不是操作系统内核。在传统TCP/IP通信中,数据从应用缓冲区到网卡需要经过用户态→内核态的多轮拷贝、协议封装、中断处理与上下文切换。每一次send/recv系统调用都涉及CPU的深度参与,而CPU处理网络协议栈的开销往往远大于数据在物理链路上的传输时间。
RDMA通过三个关键机制实现性能突破:
- 内核旁路(Kernel Bypass):应用通过Verbs API直接与HCA硬件交互,数据路径上不经过内核协议栈。用户态驱动将请求写入HCA的队列对(QP)中,硬件自行完成DMA读取、封装、传输与确认。
- 零拷贝(Zero-Copy):HCA通过DMA引擎直接访问应用注册的内存区域(MR),发送方无需将数据从应用缓冲区拷贝到内核缓冲区,接收方也无需从内核缓冲区再拷贝到应用缓冲区。数据在整个传输过程中只被硬件读取/写入一次。
- CPU卸载(CPU Offload):数据的封装/解封装、可靠传输、重传、乱序重组等原本由内核TCP/IP栈承担的工作,全部由HCA硬件完成。CPU仅在初始化、提交请求和完成通知时介入,且这些操作均为异步非阻塞。
从协议栈角度看,RDMA并非完全抛弃了分层,而是将传输层和网络层的处理逻辑下沉到硬件中。以InfiniBand为例,其协议栈包含物理层、链路层、网络层、传输层,但每一层的处理都由HCA内部的硬件状态机完成。对于RoCE(RDMA over Converged Ethernet)而言,网络层和链路层复用以太网协议,但传输层仍由HCA硬件接管。
2.2 与传统TCP/IP网络的区别:从“软件处理”到“硬件处理”
为了更直观地理解RDMA的差异,下表从多个维度对比了传统TCP/IP与RDMA(以RoCE v2为例)的通信特征:
| 对比维度 | 传统 TCP/IP(以太网) | RDMA(RoCE v2 / InfiniBand) |
|---|---|---|
| 数据路径 | 应用→内核Socket→协议栈→驱动→网卡 | 应用→Verbs API→HCA硬件(内核旁路) |
| 数据拷贝次数 | 至少2次(用户态↔内核态) | 0次(硬件DMA直接访问) |
| CPU参与度 | 每个包都触发中断与上下文切换 | 仅提交请求和接收完成通知时参与 |
| 协议处理主体 | 内核软件协议栈 | HCA硬件状态机 |
| 典型延迟 | 10~50微秒(受内核调度影响) | 1~3微秒(RoCE v2) |
| 可靠性实现 | TCP滑动窗口、重传、拥塞控制 | 硬件重传、Go-Back-N或选择性重传 |
| 内存管理 | 内核管理Socket缓冲区 | 应用注册MR,硬件直接访问 |
| 编程接口 | Socket API(send/recv) | Verbs API(ibv_post_send/ibv_poll_cq) |
| 适用场景 | 通用网络、互联网、管理面 | HPC、存储网络、AI训练、低延迟交易 |
需要特别指出的是,RDMA的“零拷贝”并非完全没有拷贝——它指的是没有CPU参与的拷贝。数据仍然会从应用内存通过PCIe总线DMA到HCA的片上缓冲区,再从片上缓冲区发送到链路。但这个过程完全由硬件DMA引擎完成,不消耗CPU周期,也不产生内核态切换。
2.3 关键术语详解:HCA、QP、CQ、MR、PD的职责与协作
RDMA的编程模型围绕一组核心对象展开。理解这些对象的职责与生命周期,是后续进行报文解析和问题排查的前提。下面逐一展开:
2.3.1 HCA(Host Channel Adapter,主机通道适配器)
HCA是RDMA系统中的“网卡”,但它远比传统NIC复杂。HCA内部集成了DMA引擎、协议处理引擎、队列管理逻辑、拥塞控制模块等。它通过PCIe接口与主机CPU和内存相连,对外提供InfiniBand或以太网端口。HCA的固件和驱动共同实现了Verbs接口,向上对应用暴露队列对(QP)、完成队列(CQ)、内存区域(MR)等抽象。
在RoCE场景中,HCA通常是一块支持RoCE的以太网卡(如Mellanox ConnectX系列),它既能处理传统以太网报文,也能识别并处理RoCE封装的RDMA报文。HCA的硬件能力直接决定了RDMA的性能上限,包括支持的最大QP数量、MR数量、报文速率、延迟等。
2.3.2 QP(Queue Pair,队列对)
QP是RDMA通信的核心对象,它由发送队列(SQ)和接收队列(RQ)组成。应用通过Verbs API向SQ提交发送请求(WR),向RQ提交接收请求(RR)。HCA硬件从SQ中取出请求,执行DMA读取、封装并发送;从RQ中取出接收请求,等待对端数据到达后DMA写入指定内存。
QP有两种主要类型:
- 可靠连接(RC,Reliable Connection):面向连接,提供可靠传输,支持RDMA Read/Write/Atomic操作。一个RC QP只能与一个对端QP通信,类似TCP的连接。
- 不可靠数据报(UD,Unreliable Datagram):无连接,类似UDP,不支持RDMA Read/Write,但支持Send/Recv操作。一个UD QP可以与多个对端QP通信。
每个QP都有一个唯一的QPN(QP Number),在通信双方建立连接时交换。QP的状态机包括RESET、INIT、RTR(Ready to Receive)、RTS(Ready to Send)等状态,只有进入RTS状态后才能正常收发数据。
2.3.3 CQ(Completion Queue,完成队列)
CQ用于通知应用其提交的WR(工作请求)是否已完成。当HCA完成一个发送或接收操作后,会生成一个完成队列元素(CQE)放入CQ中。应用通过轮询(ibv_poll_cq)或事件通知(ibv_req_notify_cq)的方式获取CQE,从而知道数据是否发送成功或接收完成。
CQ与QP是解耦的:一个CQ可以服务于多个QP,一个QP的SQ和RQ也可以分别关联不同的CQ。这种设计允许应用灵活地管理完成通知的粒度。例如,可以将高优先级的QP关联到独立的CQ,以便快速响应。
2.3.4 MR(Memory Region,内存区域)
RDMA要求参与通信的内存必须提前注册为MR。注册过程包括:锁定物理内存页(防止被换出)、建立虚拟地址到物理地址的映射表(PTE)、将映射信息写入HCA的地址转换表。注册后,HCA才能通过DMA直接访问该内存区域。
MR具有三个关键属性:
- lkey(本地键):本地HCA访问该MR时使用的密钥,用于权限校验。
- rkey(远程键):对端HCA访问本端MR时使用的密钥,用于RDMA Read/Write操作。
- 访问权限:包括本地写、远程读、远程写、原子操作等,在注册时指定。
MR的注册和注销是相对昂贵的操作(涉及内核调用和硬件表项更新),因此高性能应用通常会复用MR,而不是为每个报文单独注册。
2.3.5 PD(Protection Domain,保护域)
PD是RDMA中的资源隔离容器。一个PD可以包含多个QP、MR、AH(Address Handle,地址句柄)等资源。只有属于同一个PD的QP和MR才能相互关联使用。例如,一个QP只能提交指向本PD内MR的WR;一个MR也只能被本PD内的QP访问。
PD的作用类似于Linux中的命名空间,它防止了不同应用或不同租户之间的资源误用。在虚拟化或多租户场景中,每个租户可以拥有独立的PD,确保数据隔离和安全。
2.4 案例拆解:一次RDMA Send操作的完整生命周期
为了将上述概念串联起来,我们以一个典型的RDMA Send操作(类似TCP的send/recv)为例,展示从应用提交请求到对端收到数据的完整流程。假设节点A要向节点B发送一段数据。
前置条件:
- 节点A和节点B各自创建了HCA上下文、PD、CQ和QP,并完成了QP连接(交换QPN)。
- 节点A注册了一个MR(包含待发送数据),节点B注册了一个MR(用于接收数据)。
- 双方通过带外方式(如TCP)交换了MR的rkey和虚拟地址。
操作流程:
| 步骤 | 节点A(发送方) | 节点B(接收方) |
|---|---|---|
| 1 | 调用ibv_post_send,向QP的SQ提交一个Send WR,WR中包含MR的lkey、本地地址、长度 | 调用ibv_post_recv,向QP的RQ提交一个Receive WR,WR中包含MR的lkey、本地地址、长度 |
| 2 | HCA硬件从SQ中取出WR,通过DMA从MR中读取数据 | HCA硬件从RQ中取出WR,准备接收缓冲区 |
| 3 | HCA将数据封装为RDMA报文(包含BTH、RETH等头),通过链路发送 | HCA收到报文,解析BTH,匹配到对应的QP和RQ中的WR |
| 4 | HCA生成CQE放入CQ,标记发送完成 | HCA通过DMA将数据写入MR指定的缓冲区,生成CQE放入CQ |
| 5 | 应用调用ibv_poll_cq获取CQE,确认发送成功 | 应用调用ibv_poll_cq获取CQE,确认数据已到达 |
关键观察:在整个过程中,CPU只参与了步骤1(提交WR)和步骤5(轮询CQ),而实际的数据搬运、封装、传输、校验全部由HCA硬件完成。这正是RDMA低延迟、低CPU占用的根本原因。
2.5 常见误区与总结复盘
初学者在学习RDMA时,容易陷入以下几个误区:
- 误区一:RDMA就是“更快的TCP”。实际上,RDMA的协议栈、编程模型、错误处理与TCP完全不同。TCP的socket编程经验无法直接迁移到RDMA,需要重新学习Verbs API。
- 误区二:零拷贝意味着不需要内存注册。恰恰相反,零拷贝的前提是内存必须注册为MR,否则HCA无法通过DMA访问。MR注册本身有开销,需要合理规划。
- 误区三:QP越多越好。每个QP都会占用HCA的硬件资源(如队列深度、状态表项),过多的QP可能导致资源耗尽或性能下降。应根据并发连接数合理配置。
- 误区四:忽略PD的作用。在多应用或多租户环境中,不使用PD隔离会导致严重的安全问题。一个应用可以访问另一个应用的MR,造成数据泄露。
- 误区五:CQ轮询频率越高越好。频繁轮询CQ会消耗CPU,反而增加延迟。应根据业务需求设置合理的轮询间隔或使用事件通知机制。
总结复盘:本章的核心是建立RDMA的整体认知框架。HCA是硬件基础,QP是通信通道,CQ是完成通知机制,MR是内存访问凭证,PD是资源隔离边界。这五个概念构成了RDMA编程模型的基石。在后续章节中,我们将深入解析RDMA报文的具体格式(BTH、RETH、AETH等),以及这些概念如何在报文中体现。建议读者在阅读后续内容时,始终带着“这个字段对应哪个对象?这个操作由硬件还是软件完成?”的问题去思考。