RDMA与外卖小哥

文摘   2024-09-11 08:00   美国  

引言 — 本文首先介绍一个RDMA SEND RECV的过程,然后再具体介绍RDMA的主要概念。

除了第一段外卖小哥的解释,其余部分读起来,你如果本来就明白,那么读起来会觉得比较明白,你如果本来似懂非懂,那么读完会更明白一点,你如果本来不太懂,那么读完会觉得更加糊涂


本文分为以下三个部分:

1. 辛苦的外卖小哥

2. 必要的概念介绍

3. 其他的传输流程




I. 辛苦的外卖小哥


首先介绍一个RDMA SEND RECV的过程,RDMA就是辛苦的外卖小哥,他在送货的时候,不会打扰到你,也不会打扰到外卖系统。


他做的只是领取一份任务,送完后,标记一个完成。也就是下面的过程:


你点了一个外卖,然后把收外卖这件事情,记在了心里,

而某团的外卖系统同时会把这个订单,记录下来,包括你的住址和你的饭量,比如是两碗,还是三碗,

外卖小哥从外卖系统中接了这个活儿,并且拿到了对应的信息

外卖小哥开始送货,完成后,告诉外卖系统,外卖系统就标记一个完成。

而你收到了外卖之后,一边品尝,一边也在心里了却了一桩心事。

这就是RDMA SEND RECV


当然,也存在一种情况,比如在某水果公司上班的同学就是这样的:

你正在水果某个工厂严谨的工作,在产线上看着最新的水果16手机,

早晨的某个时候某个五星级酒店,开始准备你丰盛的午餐,自然外卖系统也会记录了这个订单,包括你的地址,和你的饭量。

当然因为你同事比较多,所以一般这种情况酒店会发出许多份,也就是大数据量传输的情况。

外卖小哥依然从外卖系统中接了这个活儿,并且拿到了对应的信息。

外卖小哥开始送货,完成后,告诉外卖系统,外卖系统就标记一个完成。

而你,也许还在工作,对于发生的这一切都不知道,因为你在产线上看到了16 Pro,想着要不要给一位正在打字的好朋友送一台。

等到午饭的时候,你发现了你的午饭,静静地躺在,那个熟悉的桌面上,你并不意外,因为你的地址,和你餐桌的偏移量等信息,你知道他们知道,他们也知道你知道他们知道。默契

这就是RDMA Write


等你吃好之后,你把高端的餐具放在餐桌上,继续返回产线,因为你看到了16 Pro Max,想着也许一位正在打字的好朋友还需要一台。

在你不经意之间,外卖小哥一如既往的把这个餐具回收,送回了五星级酒店,并且标记了一个取回任务的完成。

等你发现时,餐桌早已干干净净,没有打扰你,但是你也不意外,因为again,你的地址,和你餐桌的偏移量等信息,你知道他们知道,他们也知道你知道他们知道。默契

这就是RDMA Read


听懂掌声~

听不懂也不用继续往下看了:)接下来的不好玩了。


那么,一次SEND RECV的操作,如下图流程以及步骤解释:


  1. 接收端APP以WQE的形式下发一次RECV任务到RQ。

  2. 发送端APP以WQE的形式下发一次SEND任务到SQ。

  3. 发送端硬件从SQ中拿到任务书,从内存中拿到待发送数据,组装数据包。

  4. 发送端网卡将数据包通过物理链路发送给接收端网卡。

  5. 接收端收到数据,进行校验后回复ACK报文给发送端。

  6. 接收端硬件从RQ中取出一个任务书(WQE)。

  7. 接收端硬件将数据放到WQE中指定的位置,然后生成“任务报告”CQE,放置到CQ中。

  8. 接收端APP取得任务完成信息。

  9. 发送端网卡收到ACK后,生成CQE,放置到CQ中。

  10. 发送端APP取得任务完成信息。





II. 必要的概念介绍



什么是RDMA?

Remote Direct Memory Access

Remote:数据传输是在通过网络连接的两端

Direct:没有CPU或者OS kernel的介入

Memory:数据传输在两个app及他们的虚拟地址空间,没有额外的数据移动和复制

Access:支持send,receive,read,write以及原子操作


RDMA的主要优势:

•零拷贝(Zero Copy):零拷贝是指在数据传输过程中,避免对内存中的数据进行频繁的拷贝,从而减少CPU的开销和内存带宽的消耗。RDMA技术零拷贝的特点,允许数据绕过CPU和操作系统协议栈,直接从发送端的内存传输至接收端的内存。

•内核旁路(Kernel Bypass):内核旁路是指绕过操作系统内核,允许应用程序在用户态直接发起数据传输,从而避免内核态和用户态之间频繁的上下文切换,可以极大降低数据的传输时延。

•CPU减负(CPU Offload):RDMA技术可以在完成前期准备工作后,使数据传输过程不再需要CPU的参与,从而降低CPU资源的消耗。


RDMA如何工作?

Verbs:在RDMA的持续演进中,有一个组织叫做OpenFabric Alliance所做的贡献可谓功不可没。 Verbs这个词不好翻译,大致可以理解为访问RDMA硬件的“一组标准动作”。 每一个Verb可以理解为一个Function。

开发人员可以基于Verbs API编写RDMA应用程序并使用RDMA的所有功能,例如注册内存、创建队列、执行数据传输操作等。

与传统的TCP/IP网络不同,在RDMA通信中,数据包的解析、封装等工作都在RDMA网卡上完成,而非由操作系统内核负责。这一特性简化了数据处理流程,降低了数据传输过程的处理延迟。


队列对:

RDMA技术使用队列的机制进行数据通信,其基本通信单位是QP(Queue Pairs,队列对)。

具有RDMA引擎的以太网卡负责管理源和目标之间的可靠连接,而并非host。使用RNIC的应用程序之间采用专门的QP和CQ进行通信:

  1. 每个应用程序可以有很多的QP和CQ

  2. 每个QP包括一个SQ和RQ

  3. 每一个CQ可以和很多的SQ或者RQ关联。


队列:

Queues:RDMA一共支持三种队列,发送队列(SQ)和接收队列(RQ),完成队列(CQ)。其中,SQ和RQ通常成对创建,被称为Queue Pairs(QP)。

RDMA是基于消息的传输协议,数据传输都是异步操作。RDMA操作其实很简单,可以理解为:

  1. Host提交工作请求(WR)到工作队列(WQ): 工作队列包括发送队列(SQ)和接收队列(RQ)。工作队列的每一个元素叫做WQE, 也就是WR。

  2. Host从完成队列(CQ)中获取工作完成(WC): 完成队列里的每一个叫做CQE, 也就是WC。

  3. 具有RDMA引擎的硬件(hardware)就是一个队列元素处理器。RDMA硬件不断地从工作队列(WQ)中去取工作请求(WR)来执行,执行完了就给完成队列(CQ)中放置工作完成(WC)。从生产者-消费者的角度理解就是:

  4. Host生产WR, 把WR放到WQ中去

  5. RDMA硬件消费WR

  6. RDMA硬件生产WC, 把WC放到CQ中去

  7. Host消费WC


工作队列(WQ):

WQ是存放WQE(Work Queue Element,工作队列元素)的队列,SQ和RQ都属于WQ。

当应用程序向QP发出工作请求时,该请求会被转换为WQE并添加至WQ中。其中,发送任务会向SQ中添加WQE;接收任务会向RQ中添加WQE。

WQE包含了应用程序希望硬件设备执行的任务以及任务的详细信息,如源内存地址、目的内存地址、数据长度和Key等。硬件设备会从WQ中取出WQE,并根据WQE提供的信息执行数据传输任务。


完成队列(CQ)

为了将传输任务的执行结果返回给应用程序,RDMA中还定义了CQ(Completion Queue,完成队列)的概念。

与WQ和WQE间的关系类似,CQ中存放的队列元素称为CQE(Completion Queue Element,完成队列元素)。

当硬件设备完成传输任务后,会向CQ中添加CQE。CQE中包含了传输任务的执行结果和相关信息,应用程序可以从CQE中了解任务的执行情况。


工作请求(WR)与工作完成(WC)

由于WQE和CQE是RDMA驱动中的概念,对运行在用户态下的应用程序不可见,因此应用程序无法直接操作WQE和CQE,而是以WR(Work Request,工作请求)和WC(Work Completion,工作完成)作为“桥梁”来与QP进行交互。进行数据传输时,应用程序会调用Verbs API接口向QP下发WR。QP收到WR后会将其转换为WQE存放到WQ中。同理,完成数据传输后,CQ中的CQE会被转换为WC,返回给应用程序。

内存注册(Memory Registration)

Memory Registration,内存注册,RDMA 就是用来对内存进行数据传输。那么怎样才能对内存进行传输,很简单,注册。因为RDMA硬件对用来做数据传输的内存是有特殊要求的。

  • 在数据传输过程中,应用程序不能修改数据所在的内存。

  • 操作系统不能对数据所在的内存进行page out操作 – 物理地址和虚拟地址的映射必须是固定不变的。

注意无论是DMA或者RDMA都要求物理地址连续,这是由DMA引擎所决定的。那么怎么进行内存注册呢?

  • 创建两个key (local和remote)指向需要操作的内存区域

  • 注册的keys是数据传输请求的一部分

注册一个Memory Region之后,这个时候这个Memory Region也就有了它自己的属性:

  • context : RDMA操作上下文

  • addr : MR被注册的Buffer地址

  • length : MR被注册的Buffer长度

  • lkey:MR被注册的本地key

  • rkey:MR被注册的远程key

Memory Registration只是RDMA中对内存保护的一种措施,只有将要操作的内存注册到RDMA Memory Region中,这块操作的内存就交给RDMA 保护域来操作了。

这个时候我们就可以对这块内存进行操作,至于操作的起始地址、操作Buffer的长度,可以根据程序的具体需求进行操作。我们只要保证接受方的Buffer 接受的长度大于等于发送的Buffer长度。



III. 其他的传输过程


RDMA的数据传输:

RDMA Send/Recv

跟TCP/IP的send/recv是类似的,不同的是RDMA是基于消息的数据传输协议(而不是基于字节流的传输协议),所有数据包的组装都在RDMA硬件上完成的,也就是说OSI模型中的下面4层(传输层,网络层,数据链路层,物理层)都在RDMA硬件上完成。

RDMA Read

RDMA读操作本质上就是Pull操作, 把远程系统内存里的数据拉回到本地系统的内存里。

RDMA Write

RDMA写操作本质上就是Push操作,把本地系统内存里的数据推送到远程系统的内存里。

RDMA Write with Immediate Data

支持立即数的RDMA写操作本质上就是给远程系统Push(推送)带外(OOB)数据, 这跟TCP里的带外数据是类似的。可选的,immediate 4字节值可以与数据缓冲器一起发送。该值作为接收通知的一部分呈现给接收者,并且不包含在数据缓冲器中。


在文章开始我们讲了SEND RECV的例子,接下来讲一下Write的过程。

最大的不同就是在接收端,或者叫响应端,在开始不需要准备WQE,和CQ,而是在对收到的数据进行解析和校验之后,直接写入指定的内存区域。

而Read操作也是一种单端操作,它也是在相应段,直接将内存中的数据进行封装和传输。

(1) 请求端应用程序向QP下发一次Write WR。

(2) WR以WQE的形式被添加至SQ中。

(3) 请求端网卡从SQ中取出WQE,获取Write操作的任务信息。

(4) 请求端网卡根据WQE中的信息,从内存中获取待发送的数据并进行数据封装。

(5) 请求端网卡通过物理链路将数据发送到响应端。

(6) 响应端网卡收到数据后,对数据进行解析和校验,校验通过后将数据写入指定的内存区域中。

(7) 响应端回复确认信息给请求端网卡。

(8) 请求端网卡收到响应端回复的确认信息后,生成CQE并添加至CQ中。

(9) CQE以WC的形式返回给请求端应用程序,通知应用程序任务已完成。


(1) 请求端应用程序向QP下发一次Read WR。

(2) WR以WQE的形式被添加至SQ中。

(3) 请求端网卡从SQ中取出WQE,获取Read操作的任务信息。

(4) 请求端网卡通过物理链路将Read请求发送给响应端。

(5) 响应端网卡收到Read请求后,对数据进行解析和校验,校验通过后从内存中取出指定数据并进行数据封装。

(6) 响应端网卡通过物理链路将数据发送到请求端。

(7) 请求端网卡收到数据后,将数据存放至WQE所指定的内存区域中。

(8) 请求端网卡生成CQE并添加至CQ中。

(9) CQE以WC的形式返回给请求端应用程序,通知应用程序任务已完成。


参考文献:

  1.  RDMA基本元素:https://zhuanlan.zhihu.com/p/141267386

  2. 全网最全的RDMA拥塞控制入门基础教程                                        https://openatomworkshop.csdn.net/6673dd41a1e8811a9781dcc3.html

  3.    什么是RDMA?

       https://wiki.h3c.com/cn/detail.html?WikiName=RDMA

  4.    RDMA Tutorial

       https://www.doc.ic.ac.uk/~jgiceva/teaching/ssc18-rdma.pdf




为感谢支持,已点赞/分享/赞赏10篇/次以上的朋友,请加微信,进入微信群。我将发放免费加入知识星球的链接。

IT奶爸-知识星球




高阅读量文章





IT奶爸
实践是检验“专家”的唯一标准。一群认真执着的IT奶爸的学习和分享。
 最新文章