【协议森林】DPDK原理及使用(一)

1.简述

数据平面开发套件(DPDK ,Data Plane Development Kit)是由6WIND,Intel等多家公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。

2.基于 OS 内核的数据传输有什么弊端?

  • 1、中断处理。当网络中大量数据包到来时,会产生频繁的硬件中断请求,这些硬件中断可以打断之前较低优先级的软中断或者系统调用的执行过程,如果这种打断频繁的话,将会产生较高的性能开销。
  • 2、内存拷贝。正常情况下,一个网络数据包从网卡到应用程序需要经过如下的过程:数据从网卡通过 DMA 等方式传到内核开辟的缓冲区,然后从内核空间拷贝到用户态空间,在 Linux 内核协议栈中,这个耗时操作甚至占到了数据包整个处理流程的 57.1%。
  • 3、上下文切换。频繁到达的硬件中断和软中断都可能随时抢占系统调用的运行,这会产生大量的上下文切换开销。另外,在基于多线程的服务器设计框架中,线程间的调度也会产生频繁的上下文切换开销,同样,锁竞争的耗能也是一个非常严重的问题。
  • 4、局部性失效。如今主流的处理器都是多个核心的,这意味着一个数据包的处理可能跨多个 CPU 核心,比如一个数据包可能中断在 cpu0,内核态处理在 cpu1,用户态处理在 cpu2,这样跨多个核心,容易造成 CPU 缓存失效,造成局部性失效。如果是 NUMA 架构,更会造成跨 NUMA 访问内存,性能受到很大影响。
  • 5、内存管理。传统服务器内存页为 4K,为了提高内存的访问速度,避免 cache miss,可以增加 cache 中映射表的条目,但这又会影响 CPU 的检索效率。

综合以上问题,可以看出内核本身就是一个非常大的瓶颈所在。那很明显解决方案就是想办法绕过内核。

3.解决方案探讨

针对以上弊端,分别提出以下技术点进行探讨。

  • 1、控制层和数据层分离。将数据包处理、内存管理、处理器调度等任务转移到用户空间去完成,而内核仅仅负责部分控制指令的处理。这样就不存在上述所说的系统中断、上下文切换、系统调用、系统调度等等问题。
  • 2、使用多核编程技术代替多线程技术,并设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,减少彼此之间调度切换。
  • 3、针对 NUMA 系统,尽量使 CPU 核使用所在 NUMA 节点的内存,避免跨内存访问。
  • 4、使用大页内存代替普通的内存,减少 cache-miss。
  • 5、采用无锁技术解决资源竞争问题。

4.DPDK特点

相对传统的基于内核的网络数据处理,dpdk 对从内核层到用户层的网络数据流程进行了重大突破,我们先看看传统的数据流程和 dpdk 中的网络流程有什么不同。传统 Linux 内核网络数据流程:

硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完通知用户层-->网络层--->逻辑层--->业务层

dpdk 网络数据流程:

硬件中断--->放弃中断流程---->用户层通过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层

4.1 UIO 技术

dpdk 能够绕过内核协议栈,本质上是得益于 UIO 技术,通过 UIO 能够拦截中断,并重设中断回调行为,从而绕过内核协议栈后续的处理流程。UIO 设备的实现机制其实是对用户空间暴露文件接口,比如当注册一个 UIO 设备 uioX,就会出现文件 /dev/uioX,对该文件的读写就是对设备内存的读写。除此之外,对设备的控制还可以通过 /sys/class/uio 下的各个文件的读写来完成。
在这里插入图片描述

4.2 内存池技术

dpdk 在用户空间实现了一套精巧的内存池技术,内核空间和用户空间的内存交互不进行拷贝,只做控制权转移。这样,当收发数据包时,就减少了内存拷贝的开销。

4.3 大页内存管理

dpdk 实现了一组大页内存分配、使用和释放的 API,上层应用可以很方便使用 API 申请使用大页内存,同时也兼容普通的内存申请。

4.4 无锁环形队列

dpdk 基于 Linux 内核的无锁环形缓冲 kfifo 实现了自己的一套无锁机制。支持单生产者入列/单消费者出列和多生产者入列/多消费者出列操作,在数据传输的时候,降低性能的同时还能保证数据的同步。

4.5 poll-mode网卡驱动

DPDK网卡驱动完全抛弃中断模式,基于轮询方式收包,避免了中断开销。

4.6 NUMA

dpdk 内存分配上通过 proc 提供的内存信息,使 CPU 核心尽量使用靠近其所在节点的内存,避免了跨 NUMA 节点远程访问内存的性能问题。

4.7 CPU 亲和性

dpdk 利用 CPU 的亲和性将一个线程或多个线程绑定到一个或多个 CPU 上,这样在线程执行过程中,就不会被随意调度,一方面减少了线程间的频繁切换带来的开销,另一方面避免了 CPU 缓存的局部失效性,增加了 CPU 缓存的命中率。

4.8 多核调度框架

dpdk 基于多核架构,一般会有主从核之分,主核负责完成各个模块的初始化,从核负责具体的业务处理。

5.总结

dpdk 绕过了 Linux 内核协议栈,加速数据的处理,用户可以在用户空间定制协议栈,满足自己的应用需求,目前出现了很多基于 dpdk 的高性能网络框架,OVS 和 VPP 是常用的数据面框架,mTCP 和 f-stack 是常用的用户态协议栈。很多大公司都在使用 dpdk 来优化网络性能。

6.加入讨论

在这里插入图片描述


版权声明:本文为u012503639原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。