文章目录
阅读指南: 本文较长,请细心阅读,其中3.1节可以跳过不读。对RDMA概念有所了解的,可以直接从3.2节开始阅读。
1 传统通信模式
使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket。无论编写客户端程序还是服务端程序,系统都要为每个TCP连接都要创建一个socket句柄。这样导致了每次传输通信,都要经过OS和协议栈的管理,因此不管是Socket同步通信还是异步通信,都会存在CPU占用过高的现象。
1.1传统网络通信过程
- 数据发送方需要讲数据从用户应用空间Buffer复制到内核空间的Socket Buffer中
- 然后Kernel空间中添加数据包头,进行数据封装。通过一系列多层网络协议的数据包处理工作
- 数据被Push到NIC网卡中的Buffer进行网络传输
- 消息接受方接受从远程机器发送的数据包后,要将数据包从NIC buffer中复制数据到Socket Buffer
- 然后经过一些列的多层网络协议进行数据包的解析工作
- 解析后的数据被复制到相应位置的用户应用空间Buffer
- 这个时候再进行系统上下文切换,用户应用程序才被调用
可以看出传统的通信模式会导致重复的数据拷贝、上下文切换、CPU处理
2 RDMA基本原理与优势
2.1 基本原理
RDMA是一种新的直接内存访问技术,RDMA让计算机可以直接存取其他计算机的内存,而不需要经过处理器的处理。RDMA将数据从一个系统快速移动到远程系统的内存中,而不对操作系统造成任何影响。
RDMA:
Remote:数据通过网络与远程机器间进行数据传输
Direct:没有内核的参与,有关发送传输的所有内容都卸载到网卡上
Memory:在用户空间虚拟内存与RNIC网卡直接进行数据传输不涉及到系统内核,没有额外的数据移动和复制
Access:send、receive、read、write、atomic操作
传统的TCP/IP通信,发送和接收数据的过程中,都是在源端应用层数据从上向下逐层拷贝封装,目的端从下向上拷贝和解封装,所以比较慢,而且需要CPU参与的次数很多。RDMA通信过程中,发送和接收,读/写操作中,都是RNIC直接和参与数据传输的已经注册过的内存区域直接进行数据传输,速度快,不需要CPU参与,RDMA网卡接替了CPU的工作,节省下来的资源可以进行其它运算和服务。
更直观的对比图图:
可以看到传统的方法需要经过用户态->内核->硬件。
而RDMA直接是只经过用户态,数据的存取是通过RDMA硬件直接操作内存的。
使用RDMA的优势如下:
- 零拷贝(Zero-copy): 应用程序能够直接执行数据传输,在不涉及到网络软件栈的情况下。数据能够被直接发送到缓冲区或者能够直接从缓冲区里接收,而不需要被复制到网络层。
- 内核旁路(Kernel bypass) - 应用程序可以直接在用户态执行数据传输,不需要在内核态与用户态之间做上下文切换。
- 不需要CPU干预(No CPU involvement) - 应用程序可以访问远程主机内存而不消耗远程主机中的任何CPU。远程主机内存能够被读取而不需要远程主机上的进程(或CPU)参与。远程主机的CPU的缓存(cache)不会被访问的内存内容所填充。
- 消息基于事务(Message based transactions) - 数据被处理为离散消息而不是流,消除了应用程序将流切割为不同消息/事务的需求。
- 支持分散/聚合条目(Scatter/gather entries support) - RDMA原生态支持分散/聚合。也就是说,读取多个内存缓冲区然后作为一个流发出去或者接收一个流然后写入到多个内存缓冲区里去。
3 RDMA原理详解
3.1 支持RDMA的网络协议
目前支持RDMA的网络协议主要有三种
- InfiniBand(IB)
- iWARP(RDMA over TCP/IP)
- RoCE(RDMA over Converged Ethernet)
- RoCEv1和RoCEv2
- RoCEv1和RoCEv2
InfiniBand 通过以下技术保证网络转发的低时延( 亚微秒级 ), 采用Cut-Through转发模式,减少转发时延;基于Credit的流控机制,保证无丢包;硬件卸载;Buffer尽可能小,减少报文被缓冲的时延 。
iWARP(RDMA over TCP/IP) 利用成熟的IP网络; 继承RDMA的优点;TCP/IP硬件实现成本高,但如果采用传统IP网络的丢包策略对性能影响大 。
**RDMA over Converged Ethernet (RoCE)**是一种网络协议,允许应用通过以太网实现远程内存访问。目前RoCE有两个协议版本。
RoCE v1是一种链路层协议,允许在同一个广播域下的任意两台主机直接访问。
RoCE v2是一种Internet层协议,即可以实现路由功能。虽然RoCE协议这些好处都是基于融合以太网的特性,但是RoCE协议也可以使用在传统以太网网络或者非融合以太网络中。
RoCE和InfiniBand,一个定义了如何在以太网上运行RDMA,而另一个则定义了如何在IB网络(主要是基于集群的应用)中运行RDMA
RoCE和iWARP,一个是基于无连接协议UDP,一个是基于面向连接的协议(如TCP)。
目前,虽然IB、以太网RoCE、以太网iWARP这三种RDMA技术使用统一的API,但它们有着不同的物理层和链路层。在以太网解决方案中,RoCE相对于iWARP来说有着明显的优势,这些优势体现在延时、吞吐率和 CPU负载。RoCE被很多主流的方案所支持,并且被包含在Windows服务软件中
3.2 核心概念
RDMA是基于消息的数据传输协议(而不是基于字节流的传输协议),所有数据包的组装都在RDMA硬件上完成的,也就是说OSI模型中的下面4层(传输层,网络层,数据链路层,物理层)都在RDMA硬件上完成。
一个名为OpenFabric Alliance的组织)提供了RDMA传输的一系列Verbs API,开发了OFED(Open Fabric Enterprise Distribution)协议栈,支持多种RDMA传输层协议。
RDMA应用和RNIC(RDMA-aware Network Interface Controller)之间的传输接口层(Software Transport Interface)被称为Verbs或RDMA API
RDMA API (Verbs)主要有两种Verbs:
-
内存Verbs(Memory Verbs),也叫One-SidedRDMA。包括RDMA Reads, RDMA Writes, RDMA Atomic。这种模式下的RDMA访问完全不需要远端机的任何确认。
-
消息Verbs(Messaging Verbs),也叫Two-SidedRDMA。包括RDMA Send, RDMA Receive。这种模式下的RDMA访问需要远端机CPU的参与。
在实际中, SEND /RECEIVE多用于连接控制类报文,而数据报文多是通过READ/WRITE来完成的 。
3.2.1 基本概念
1、Memory Registration(MR) | 内存注册
创建两个key (local和remote)指向需要操作的内存区域,注册的keys是数据传输请求的一部分。
同时,RDMA硬件对用来做数据传输的内存是有特殊要求的。
- 在数据传输过程中,应用程序不能修改数据所在的 内存。
- 操作系统不能对数据所在的内存进行page out操作 – 物理地址和虚拟地址的映射必须是固定不变的
2、Queues | 队列
RDMA一共支持三种队列,发送队列(SQ)和接收队列(RQ),完成队列(CQ)。其中,SQ和RQ通常成对创建,被称为Queue Pairs(QP)。
RDMA是基于消息的传输协议,数据传输都是异步操作。 RDMA操作其实很简单,可以理解为:
- Host提交工作请求(WR)到工作队列(WQ): 工作队列包括发送队列(SQ)和接收队列(CQ)。工作队列的每一个元素叫做WQE, 也就是WR。
- Host从完成队列(CQ)中获取工作完成(WC): 完成队列里的每一个叫做CQE, 也就是WC。
- 具有RDMA引擎的硬件(hardware)就是一个队列元素处理器。 RDMA硬件不断地从工作队列(WQ)中去取工作请求(WR)来执行,执行完了就给完成队列(CQ)中放置工作完成(WC)。
从生产者-消费者的角度理解就是:
- Host生产WR, 把WR放到WQ中去
- RDMA硬件消费WR
- RDMA硬件生产WC, 把WC放到CQ中去
- Host消费WC
3、Send/Recv操作
SEND/RECEIVE是双边操作,即需要通信双方的参与,并且RECEIVE要先于SEND执行,这样对方才能发送数据,当然如果对方不需要发送数据,可以不执行RECEIVE操作,因此该过程和传统通信相似,区别在于RDMA的零拷贝网络技术和内核旁路,延迟低,多用于传输短的控制消息。
4、read/write操作
-
RDMA读操作本质上就是Pull操作, 把远程系统内存里的数据拉回到本地系统的内存里。
- 接收方必须提供虚拟地址和目标存储内存的remote_key。
- 接收方需要初始和接受提醒通知,发送方是完全被动的,并且不会接受任何通知
-
RDMA写操作本质上就是Push操作,把本地系统内存里的数据推送到远程系统的内存里。
- 发送方必须提供虚拟地址和目标读取内存的remote_key。
- 发送方需要初始和接受提醒通知,接受方是完全被动的,并且不会接受任何通知
3.2.2 RDMA工作流程
要使用RDMA首先要建立从RDMA到应用程序内存的数据路径 ,可以通过RDMA专有的verbs interface接口来建立这些数据路径,一旦数据路径建立后,就可以直接访问用户空间buffer。
RDMA 的工作过程如下:
- 初始化context,注册内存域
- 建立RDMA连接
- 通过SEND/RECEIVE操作,C/S交换包含RDMA memory region key的MSG_MR消息(一般是客户端先发送)
- 通过WRITE/READ操作,进行数据传输(单边操作)
- 发送MSG_DONE消息,关闭连接
更细节化的流程描述:
- 消息服务建立在通信双方本端和远端应用之间创建的Channel-IO连接之上。当应用需要通信时,就会创建一条Channel连接,每条Channel的首尾端点是两对Queue Pairs(QP)。
- 每对QP由Send Queue(SQ)和Receive Queue(RQ)构成,这些队列中管理着各种类型的消息。QP会被映射到应用的虚拟地址空间,使得应用直接通过它访问RNIC网卡。
- 除了QP描述的两种基本队列之外,RDMA还提供一种队列Complete Queue(CQ),CQ用来知会用户WQ上的消息已经被处理完。
- RDMA提供了一套软件传输接口,方便用户创建传输请求Work Request(WR),WR中描述了应用希望传输到Channel对端的消息内容,WR通知QP中的某个队列Work Queue(WQ)。
- 在WQ中,用户的WR被转化为Work Queue Element(WQE)的格式,等待RNIC的异步调度解析,并从WQE指向的Buffer中拿到真正的消息发送到Channel对端。
RDMA双边操作(send/receive)
对于双边操作为例,A向B发送数据的流程如下:
-
首先,A和B都要创建并初始化好各自的QP,CQ
-
A和B分别向自己的WQ中注册WQE,对于A,WQ=SQ,WQE描述指向一个等到被发送的数据;对于B,WQ=RQ,WQE描述指向一块用于存储数据的buffer。
-
A的RNIC异步调度轮到A的WQE,解析到这是一个SEND消息,从buffer中直接向B发出数据。数据流到达B的RNIC后,B的WQE被消耗,并把数据直接存储到WQE指向的存储位置。
-
AB通信完成后,A的CQ中会产生一个完成消息CQE表示发送完成。与此同时,B的CQ中也会产生一个完成消息表示接收完成。每个WQ中WQE的处理完成都会产生一个CQE。
双边操作与传统网络的底层buffer pool类似,收发双方的参与过程并无差别,区别在零拷贝、kernel bypass,实际上传统网络中一些高级的网络SOC已经实现类似功能。对于RDMA,这是一种复杂的消息传输模式,多用于传输短的控制消息。
RDAM单边操作(read)
READ和WRITE是单边操作,只需要本端明确信息的源和目的地址,远端应用不必感知此次通信。对于操作发起端,数据的读或写都通过在RNIC与应用Buffer之间完成,再由远端RNIC封装成消息返回到本端。
对于单边操作,以B对A的read操作为例,数据的流程如下:
- 首先A、B建立连接,QP已经创建并且初始化。
- 数据被存档在A的buffer地址VA,注意VA应该提前注册到A的RNIC,并拿到返回的local key,相当于RDMA操作这块buffer的权限。
- A把数据地址VA,key封装到专用的报文传送到B,这相当于A把数据buffer的操作权交给了B。同时A在它的WQ中注册进一个WR,以用于接收数据传输的B返回的状态。
- B在收到A的送过来的数据VA和R_key后,RNIC会把它们连同存储地址VB到封装RDMA READ,这个过程A、B两端不需要任何软件参与,就可以将A的数据存储到B的VB虚拟地址。
- B在存储完成后,会向A返回整个数据传输的状态信息。
单边操作传输方式是RDMA与传统网络传输的最大不同,只需提供直接访问远程的虚拟地址,无须远程应用的参与其中,这种方式适用于批量数据传输。
注:作者水平有限,如有错误欢迎指正
参考链接:
https://blog.****.net/cjqxiong/article/details/78814213
https://blog.****.net/qq_21125183/article/details/80563463
https://www.cnblogs.com/vlhn/p/7909893.html
https://blog.****.net/zjttlance/article/details/80318763
https://www.sohu.com/a/229080366_632967
https://blog.****.net/upupday19/article/details/79377984