网络的发展好像在各方面都是滞后于计算和存储,时延方面也不例外,网络传输时延高,逐渐成为了数据中心高性能的瓶颈。因为传统两个节点间传输数据的网络路径上有大量的内存拷贝,导致网络传输效率低下,网络数据包的收发处理路径如下图所示:
普通物理机上收发包 虚拟机环境上收发包(从host物理机到虚拟机)
为了解决此问题,有2种方案:RDMA和DPDK
一:RDMA
RDMA( Remote Direct Memory Access,远程直接地址访问技术 )是一种新的内存访问技术,RDMA将服务器应用数据直接由内存传输到智能网卡(固化RDMA协议),由智能网卡硬件完成RDMA传输报文封装,这样就可以让服务器直接高速读写其他服务器的内存数据,而不需要经过操作系统/CPU耗时的处理。具体看如下:
RDMA的内核旁路机制允许应用与网卡之间的直接数据读写,规避了TCP/IP的限制,将协议栈时延降低到接近1us。RDMA的内存零拷贝机制,无需在应用程序内存和操作系统中的数据缓冲区之间复制数据。这样的传输不需要CPU、缓存或上下文切换器完成任何工作,大幅度降低了消息传输中的处理延迟,同时传输与其他系统操作并行进行,提高了网络传输的性能。
传统模式和RDMA模式的对比
通过对比传统模式和RDMA模式对发送和接收数据的处理过程,RDMA技术最大的突破在于给数据中心通信架构带来了低时延、超低的CPU和内存资源占用率等特性。
低时延主要体现在RDMA的零拷贝网络和内核旁路机制。零拷贝网络网卡可以直接与应用内存相互传输数据,消除了在应用内存与内核内存之间的数据复制操作,使传输延迟显著降低。内核内存旁路机制使应用程序无需执行内核内存调用就可向网卡发送命令。在不需要任何内核内存参与的条件下,RDMA请求从用户空间发送到本地网卡,再通过网络发送给远程网卡,这就减少了在处理网络传输流时内核内存空间与用户空间之间环境切换的次数,降低了网络时延。
超低CPU和内存资源占用率主要体现在应用程序可以直接访问远程内存,而不占用远程服务器中的任何CPU资源,远程CPU中的缓存资源也不会被访问的内容填满,服务器可以将几乎100%的CPU资源和内存资源提供给计算或其他的服务,节省了服务器资源占用的同时,提高了服务器数据处理带宽。
二:DPDK
DPDK是Data Plane Development Kit的缩写。简单说,DPDK应用程序运行在操作系统的User Space,利用自身提供的数据面库进行收发包处理,绕过了Linux内核态协议栈,以提升报文处理效率。
DPDK是一组lib库和工具包的集合。最简单的架构描述如下图所示:
上图蓝色部分是DPDK的主要组件(更全面更权威的DPDK架构可以参考Intel官网),简单解释一下:
PMD:Pool Mode Driver,轮询模式驱动,通过非中断,以及数据帧进出应用缓冲区内存的零拷贝机制,提高发送/接受数据帧的效率
流分类:Flow Classification,为N元组匹配和LPM(最长前缀匹配)提供优化的查找算法
环队列:Ring Queue,针对单个或多个数据包生产者、单个数据包消费者的出入队列提供无锁机制,有效减少系统开销
MBUF缓冲区管理:分配内存创建缓冲区,并通过建立MBUF对象,封装实际数据帧,供应用程序使用
EAL:Environment Abstract Layer,环境抽象(适配)层,PMD初始化、CPU内核和DPDK线程配置/绑定、设置HugePage大页内存等系统初始化
这么说可能还有一点点抽象,再总结一下DPDK的核心思想:
用户态模式的PMD驱动,去除中断,避免内核态和用户态内存拷贝,减少系统开销,从而提升I/O吞吐能力
用户态有一个好处,一旦程序崩溃,不至于导致内核完蛋,带来更高的健壮性
HugePage,通过更大的内存页(如1G内存页),减少TLB(Translation Lookaside Buffer,即快表) Miss,Miss对报文转发性能影响很大
多核设备上创建多线程,每个线程绑定到独立的物理核,减少线程调度的开销。同时每个线程对应着独立免锁队列,同样为了降低系统开销
向量指令集,提升CPU流水线效率,降低内存等待开销
下图简单描述了DPDK的多队列和多线程机制:
DPDK将网卡接收队列分配给某个CPU核,该队列收到的报文都交给该核上的DPDK线程处理。存在两种方式将数据包发送到接收队列之上:
RSS(Receive Side Scaling,接收方扩展)机制:根据关键字,比如根据UDP的四元组<srcIP><dstIP><srcPort><dstPort>进行哈希
Flow Director机制:可设定根据数据包某些信息进行精确匹配,分配到指定的队列与CPU核
当网络数据包(帧)被网卡接收后,DPDK网卡驱动将其存储在一个高效缓冲区中,并在MBUF缓存中创建MBUF对象与实际网络包相连,对网络包的分析和处理都会基于该MBUF,必要的时候才会访问缓冲区中的实际网络包
对比:
DPDK | RDMA | |
网络层 | 硬件中断->放弃中断流程; 用户层通过设备映射取包->进入用户层协议栈->逻辑层->业务层; | |
核心技术 | 1)将协议栈上移到用户态,利用UIO技术直接将设备数据映射拷贝到用户态 2)利用大页技术,降低TLB cache miss,提高TLB访问命中率 3)通过CPU亲和性,绑定网卡和线程到固定的core,减少cpu任务切换 4)通过无锁队列,减少资源的竞争 | 协议栈硬件offload |
优势 | 1)减少中断次数; 2)减少内存拷贝次数 3)绕过linux的协议栈,用户获得协议栈的控制权,能够定制化协议栈以降低复杂度; | 1)协议栈offload,解放cpu 2)减少了中断和内存拷贝,降低时延 3)高带宽 |
劣势 | 1)内核栈转移至用户层增加了开发成本 2)低负荷服务器不实用,会造成cpu空转 | 1)特定网卡才支持,成本开销相对较大; 2)RDMA提供了完全不同于传统网络编程的API,一般需要对现有APP进行改造,引入额外开发成本 |
总结
相同点:
1)两者均为kernel bypass技术,可以减少中断次数,消除内核态到用户态的内存拷贝;
相异点:
1)DPDK是将协议栈上移到用户态,而RDMA是将协议栈下沉到网卡硬件,DPDK仍然会消耗CPU资源;
2)DPDK的并发度取决于CPU核数,而RDMA的收包速率完全取决于网卡的硬件转发能力
3)DPDK在低负荷场景下会造成CPU的无谓空转,RDMA不存在此问题
4)DPDK用户可获得协议栈的控制权,可自主定制协议栈;RDMA则无法定制协议栈
DPDK是Intel主导,提供了基于用户态的数据链路层的功能,可以在上面构建出基于用户态的网络栈。实际使用中一个显然的缺点是只有poll功能,没有陷入中断来减少对CPU的消耗(空转问题)。
参考文档:
https://blog.csdn.net/bandaoyu/article/details/112588762
https://blog.csdn.net/oldboy_1983/article/details/79474750
【DPDK】Linux UIO技术_bandaoyu的博客-CSDN博客