1.背景
场景一:项目有一个硬盘里有装载数据的文件需要处理,最常用的处理方法是:通过应用程序去读取文件,解析里面的数据,然后再对数据进行处理。文件比较大时,电脑很可能会卡死,长时间无法执行其他操作。
场景二:通过USB接口外接一个硬盘,然后把硬盘上的文件拷贝到电脑的某个磁盘上,如果硬盘上的文件比较大,那么电脑也可能卡死,长时间无法执行其他操作。
为什么读/写/拷贝较大文件时,电脑很可能会卡死,长时间无法执行其他操作?如何能在拷贝大量数据的文件时,系统还能正常运行,不卡死?
2.原因
假设I/O设备为一个普通网卡,为了从内存拿到需要发送的数据,然后组装数据包发送到物理链路上,网卡需要通过总线告知CPU自己的数据请求。然后CPU将会把内存缓冲区中的数据复制到自己内部的寄存器中,再复制到I/O设备的存储空间中。如果数据量比较大,那么很长一段时间内CPU都会忙于搬移数据,而无法投入到其他工作中去,这就导致电脑很可能会卡死,长时间无法执行其他操作。
3.技术方案:引入DMA技术
I/O设备(如网卡)上新增一个模块DMA控制器,也就是说一块网卡中既有负责数据收发的模块,也有DMA模块,并将新增的DMA控制器与总线上相连,用DMA控制器专门用来读/写内存的设备。
有了DMA模块后,当网卡想要从内存中拷贝数据时,除了一些必要的控制命令外,整个数据复制过程都是由DMA控制器完成的。过程跟CPU复制是一样的,只不过这次是把内存中的数据通过总线复制到DMA控制器内部的寄存器中,再复制到I/O设备的存储空间中。CPU除了关注一下这个过程的开始和结束以外,其他时间可以去做其他事情。
4.什么是DMA技术
DMA全称为Direct Memory Access,即直接内存访问。意思是外设对内存的读/写过程可以不用CPU参与而直接进行。注意,并不是完全没有,cpu对读/写本身不控制,但是对读/写进行整体过程关注,而不是细节。
5.什么是RDMA技术
2台电脑之间通过网路相连,相互之间发送大文件,就是RDMA的应用场景。
传统网络的数据传输(如数据从电脑A到电脑B)的流程如下:
电脑A上,在内存用户空间中的数据,需要经过CPU拷贝到内核空间的缓冲区中;缓冲区中的数据会经过软件实现的TCP/IP协议栈,加上各层头部和校验码,比如TCP头,IP头等,然后拷贝给网卡;网卡通过DMA拷贝内核中的数据到网卡内部的缓冲区中,进行处理后通过物理链路发送给电脑B网卡。
电脑B网卡收到数据后,会进行相反的过程:从网卡内部存储空间,将数据通过DMA拷贝到内存内核空间的缓冲区中;然后CPU会通过TCP/IP协议栈对其进行解析,将数据取出来拷贝到用户空间中。
可以看到,即使有了DMA技术,上述过程还是对CPU有较强的依赖。
RDMA( Remote Direct Memory Access )意为远程直接地址访问,通过RDMA,本端节点可以“直接”访问远端节点的内存。所谓直接,指的是可以像访问本地内存一样,绕过传统以太网复杂的TCP/IP网络协议栈读写远端内存,而这个过程对端是不感知的,而且这个读写过程的大部分工作是由硬件而不是软件完成的。
基于RDMA的网络数据传输(如数据从电脑A到电脑B)的流程如下:
使用了RDMA技术,两端的CPU几乎不用参与数据传输过程(只参与控制面)。本端的网卡直接从内存的用户空间DMA拷贝数据到内部存储空间,然后硬件进行各层报文的组装后,通过物理链路发送到对端网卡。对端的RDMA网卡收到数据后,剥离各层报文头和校验码,通过DMA将数据直接拷贝到用户空间内存中。
两个流程相比:少了CPU参与内存在内核空间的拷贝;少了CPU参与上下文的切换。
6.RDMA技术的特点
6.1 零拷贝
零拷贝技术是指计算机执行操作时,CPU不需要在用户空间和内核空间中来回复制数据。。
可见,零拷贝的特点是 CPU 不全程负责内存中的数据写入其他组件,CPU 仅仅起到管理的作用。但注意,零拷贝不是不进行拷贝,而是 CPU 不再全程负责数据拷贝时的搬运工作。如果数据本身不在内存中,那么必须先通过某种方式拷贝到内存中(这个过程 CPU 可以不参与),因为数据只有在内存中,才能被转移,才能被 CPU 直接读取计算。
6.2 内核Bypass
指的是IO(数据)流程可以绕过内核,即在用户层就可以把数据准备好并通知硬件准备发送和接收。避免了系统调用和上下文切换的开销。
6.3 CPU卸载
传统tcp/ip协议,需要CPU对内核中的数据进行打包/解包操作,而RDMA在网卡上有DMA控制器,可以直接对数据进行打包/解包操作。
7.协议
RDMA本身指的是一种技术,具体协议层面,包含Infiniband(IB),RDMA over Converged Ethernet(RoCE)和internet Wide Area RDMA Protocol(iWARP)。三种协议都符合RDMA标准,使用相同的上层接口,在不同层次上有一些差别。
8 RDMA社区
对于上层用户,IB提供了一套与Socket套接字类似的接口——libibverbs,前文所述三种协议都可以使用。参考着协议、API文档和示例程序很容易就可以写一个Demo出来。本专栏中的RDMA社区专指其用户态社区,在github上其仓库的名字为linux-rdma。
主要包含两个子仓库:
- rdma-core
用户态核心代码,API,文档以及各个厂商的用户态驱动。
- perftest
一个功能强大的用于测试RDMA性能的工具。