一、RDMA与Socket通信比较
1.Socket通信
概述: Socket通信通过使用套接字(Socket)作为编程接口可以在不同的计算机之间建立连接,并通过发送和接收数据来实现通信。在Socket通信中有两个主要角色:服务器和客户端。服务器通常在网络上的某个节点上监听指定的端口,等待客户端连接。而客户端则通过指定服务器的IP地址和端口号来连接服务器。
通信过程:
- 发送端和接收端通过Socket库提供的接口建立连接(即两个节点间建立一条逻辑通路)并分别在内存中申请发送和接收Buffer。
- 发送端APP通过Socket接口陷入内核态,待发送数据经过TCL/IP协议栈的封装被CPU复制Socket Buffer中。
- 发送端通过网卡驱动告诉网卡可以发送数据,网卡通过DMA从Buffer中复制封装好的数据到内部缓存中,然后将其发送到物理链路。
- 接收端网卡收到数据包后,将数据放到接收Buffer中,然后CPU通过内核的TCP/IP协议栈对报文进行解析,取出有效的数据。
- 接收端APP通过Socket接口陷入内核态,CPU将数据从内核空间复制到用户空间。
数据流向:
发送端
- 数据首先需要从用户空间复制一份到内核空间的Socket Buffer中,这一次复制由CPU完成
- 网卡通过DMA从内存中复制数据(经由TCP/IP封装后)
- 通过物理链路发送给对端网卡
接收端
- 网卡接收数据后通过DMA将数据拷贝到内存中
- CPU对数据包进行解析
- CPU将解析后的数据复制到用户空间
传统的Socket网络通信中,数据的传输需要经过操作系统内核的拷贝操作,首先将数据从发送方的应用层复制到内核缓冲区,再将数据从内核缓冲区复制到接收方的应用程序中,这个过程涉及到多次数据拷贝和上下文切换,导致了较高的延迟和CPU开销。
2.RDMA通信
概述: RDMA通信是一种高性能的网络通信技术,允许计算机系统之间直接访问对方内存中的数据,而无需操作系统的干预或数据在中间缓冲区的复制。
通信过程:
这里的控制通路需要进入内核态准备通信所需的内存资源,而数据通路指的是实际数据交互过程中的流程。
- 发送端和接收端分别通过控制通路陷入内核态创建好通信所需要的内存资源。
- 在数据通路上,接收端APP通知硬件准备接收数据,告诉硬件将接收到的数据放在哪片内存中。
- 在数据通路上,发送端APP通知硬件发送数据,告诉硬件待发送的数据在哪片内存中。
- 发送端RDMA网卡从内存中搬移数据,组装报文发送给对端
- 对端收到报文并对其进行解析通过DMA写入内存,通知上层APP告知其数据已接收并存放到指定数据。
数据流向:
数据收发绕过了内核并且数据交换过程并不需要CPU参与,报文的组装和解析是由硬件完成的。
RDMA通信将CPU从数据包封装和解析中解放出来,又减少了CPU拷贝数据的功率和时间损耗。
二、RDMA基本元素
概述:Infiniband网络接口卡称为HCA(主机通道适配器),HCA使用工作队列队列互相通信,队列的三种类型有:(1)接受队列(RQ)、(2)发送队列(SQ)、(3)完成队列(CQ)。其中SQ和RQ始终作为队列对(QP)进行分组和管理。
缩略语:
- WQ(Work Queue):工作队列
- WQE(Work Queue Element):工作队列元素
- QP(Queue Pair):队列队
- SQ(Send Queue):发送队列
- RQ(Recieve Queue):接收队列
- SRQ(Shared Recieve Queue):共享接收队列
- CQ(Completion Queue):完成队列
- CQE(Completion Queue Element):完成队列元素
- WR(work Request):工作请求
- WC(Work Completion):工作完成
WQ/WQE:
WQE指的是软件下发给硬件的明确工作请求,而WQ是用来存放WQE的队列。使用WQ保证了工作请求都是由软件发起,且由硬件执行的。所有的通信请求都需按下图方式告知硬件,这种方式称为Post。
SQ/RQ/QP
通信过程中双方都需要有发送和接收两端,发送队列和接收队列组合成一个队列队。下图左边是发送端,右边是接收端。
Post操作对于SQ而言称为Post Send,对于RQ来说称为Post Recieve。值得注意的是,在RDMA中通信的基本单元是QP(队列对),而不是节点。每个节点的每个进程可以有若干个QP,其中用QPN来唯一标识。
SRQ
当几个QP共享同一个RQ时,我们称这个RQ为共享接收队列。接收队列(RQ)的使用频率通常会小于发送队列(SQ)的使用频率。当需要使用大量的QP时,可以通过SRQ来节省空间。
CQ/CQE
CQE的概念与WQE相反,WQE是软件下发给硬件的任务请求,而CQE则是硬件完成任务后返回给软件的报告,描述任务是否被正确无误的执行,遇到了错误及原因等。而CQ则是包含CQE的队列。
在一次SEND-RECIEVE操作中,软硬件操作如下图所示:
- 接收端硬件从RQ拿到任务,准备接收数据
- 发送端APP以WQE形式下发一次Post Send
- 发送端硬件从SQ中拿到任务,从内存中拿到待发送数据,组装数据包
- 发送端网卡将数据包通过物理链路发送给接收端网卡
- 接收端收到数据,校验后回复ACK报文给发送端
- 接收端硬件将数据放到WQE指定的位置,然后生成CQE,放置到CQ中
- 接收端APP取得任务完成信息
- 发送端网卡收到ACK后,生成CQE并放置到CQ中
- 发送端APP取得任务完成信息
WR/WC
WR和WC是WQE、CQE在用户层的映射。用户层APP是通过调用协议栈接口来完成RDMA通信的,WQE、CQE本身对用户不可见,是驱动中的概念,用户真正通过API下发的是WR,收到的是WC。