DPDK — 数据平面开发技术

目录

前文列表

DPDK — 安装部署

内核协议栈的数据转发性能瓶颈是什么?

在 x86 体系结构中,接受数据包的传统方式是 CPU 中断方式,即网卡驱动接收到数据包后通过中断通知 CPU 处理,然后由 CPU 拷贝数据并交给内核协议栈。在数据量大时,这种方式会产生大量 CPU 中断,导致 CPU 无法运行其他程序。

内核协议栈的数据转发流程
在这里插入图片描述

详细的转发流程请浏览下列文章,这里不再赘述。

内核协议栈的数据转发性能瓶颈有

  • 硬件中断导致的线程/进程切换:硬件中断请求会抢占优先级较低的软件中断,频繁到达的硬件中断和软中断意味着频繁的线程切换,随着而来的就是运行模式切换、上下文切换、线程调度器负载、高速缓存缺失(Cache Missing)、多核缓存共享数据同步、竞争锁等一系列的 CPU 性能损耗。
  • 内存拷贝:网卡驱动位于内核态,网络驱动接收到的数据包后会经过内核协议栈的处理,然后再拷贝到处于用户态的应用层缓冲区,这样的数据拷贝是很耗时间的。据统计,这个拷贝的时间会占数据包处理流程时间的 57.1%。
  • 多处理器平台的 CPU 漂移:一个数据包可能中断在 CPU0,内核态处理在 CPU1,用户态处理在 CPU2,这样跨多个物理核(Core)的处理,导致了大量的 CPU Cache Miss,造成局部性失效。如果是 NUMA 架构,还会出现跨 NUMA remote access Memory 的情况,这些都极大地影响了 CPU 性能。
  • 缓存失效:传统服务器大多采用页式虚拟存储器,内存页默认为 4K 的小页,所以在存储空间较大的处理机上会存在大量的页面映射条目。同时因为 TLB 缓存空间有限,最终导致了 TLB 快表的映射条目频繁变更,产生大量的快页表 Cache Miss。

故此,对应的优化方案为

  • 使用 NUMA 亲和:避免 CPU 跨 NUMA 访问内存。
  • 使用 CPU 绑核:避免跨 CPU 的线程/进程切换。
  • 使用大页内存:避免 TLB Cache Miss。
  • 使用 DPDK:内核旁路技术避免了频繁的硬件中断和无效数据拷贝。

DPDK 完全内核旁路技术实现

DPDK(Data Plane Development Kit,数据平面开发套件)是一个开源的、快速处理数据平面数据包转发的开发平台及接口。运行于 Intel x86 与 ARM 平台上,最新版本也开始支持 PowerPC。

英特尔在 2010 年启动了对 DPDK 技术的开源化进程,于当年 9 月通过 BSD 开源许可协议正式发布源代码软件包,并于 2014 年 4 月在 www.dpdk.org 上正式成立了独立的开源社区平台,为开发者提供支持。开源社区的参与者们大幅推进了 DPDK 的技术创新和快速演进,而今它已发展成为 SDN 和 NFV 的一项关键技术。

DPDK 提供了一个用户态的高效数据包处理库函数,它通过环境抽象层、内核旁路协议栈、轮询模式的报文无中断收发、优化内存/缓冲区/队列管理、基于网卡多队列和流识别的负载均衡等多项技术,实现了在 x86 处理器架构下的高性能报文转发能力,用户可以在 Linux 用户态开发各类高速转发应用,也适合与各类商业化的数据平面加速解决方案进行集成。简而言之,DPDK 重载了网卡驱动,将数据包的控制平面和数据平面分离,驱动在收到数据包后不再硬中断通知 CPU,而是让数据包通过内核旁路的协议栈绕过了 Linux 内核协议栈,并通过零拷贝技术存入内存,这时应用层的程序就可以通过 DPDK 提供的接口读取数据包

DPDK 数据包处理流程
在这里插入图片描述
这种处理方式节省了 CPU 中断时间、内存拷贝时间,并向应用层提供了简单易行且高效的数据包处理接口函数,使得网络应用的开发更加方便。但同时,由于需要重载网卡驱动,因此该开发包目前只能用在部分采用 Intel 网络处理芯片的网卡设备中。DPDK 支持的网卡列表:https://core.dpdk.org/supported/,主流使用 Intel 82599(光口)和 Intel x540(电口)。DPDK 可以将数据包处理性能最多提高十倍。在单个英特尔至强处理器上获得超过 80 Mbps 的吞吐量,在双处理器配置中则可将该其提高一倍。

DPDK 实现原理

在这里插入图片描述

  • 内核协议栈(左边):网卡 -> 驱动 -> 协议栈 -> Socket 接口 -> 业务。
  • DPDK 基于 UIO(User Space I/O)的内核旁路(右边):网卡 -> DPDK 轮询模式-> DPDK 基础库 -> 业务。

NOTE:说 DPDK 依赖网卡设备不如说 DPDK 依赖的是网卡设备对应的驱动程序。支持 DPDK 的 NIC Kernel Driver 可以转换为 UIO Driver 模式。由此,如有需要,DPDK 实际上是可以在虚拟机上使用的,只要虚拟机的网卡驱动支持 DPDK PMD 模式,例如:e1000。

UIO Framework,DPDK 的基石

传统的收发数据包方式,首先网卡通过中断方式通知内核协议栈对数据包进行处理,内核协议栈先会对数据包进行合法性进行必要的校验,然后判断数据包目标是否为本机的 Socket,满足条件则会将数据包拷贝一份向上递交到用户态 Socket 来处理。不仅处理路径冗长,还需要从内核到应用层的一次拷贝过程。

为了使得网卡驱动(e.g. PMD Driver)运行在用户态,实现内核旁路。Linux 提供了 UIO(User Space I/O)机制。使用 UIO 可以通过 read() 感知中断,通过 mmap() 实现和网卡设备的通讯。

简单来说,UIO 是用户态的一种 I/O 技术,DPDK 能够绕过内核协议栈,提供了用户态 PMD Driver 的支持,根本上是得益于 UIO 技术。DPDK 架构在 Linux 内核中安装了 IGB_UIO(igb_uio.ko 和 kni.ko.IGB_UIO)模块,以此借助 UIO 技术来截获中断,并重设中断回调行为,从而绕过内核协议栈后续的处理流程。并且 IGB_UIO 会在内核初始化的过程中将网卡硬件寄存器映射到用户态。

UIO 的实现机制是:对用户态暴露文件接口。当注册一个 UIO 设备 uioX 时,就会出现系统文件 /dev/uioX,对该文件的读写就是对网卡设备内存的读写。除此之外,对网卡设备的控制还可以通过 /sys/class/uio 下的各个文件的读写来完成。如下图:

在这里插入图片描述

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

DPDK UIO

综上,DPDK 基于 Linux Kernel 的 UIO 框架完成了其自身的 UIO 实现。DPDK UIO 实现主要分为用户态(DPDK PMD)与内核态(igb_uio)两个部分。用户态部分实现真正的数据转发业务处理,内核态部分主要是接管硬件资源提供给用户态部分使用。

在这里插入图片描述

我们可以将整个 DPDK UIO 的框架分了四层:

  1. 用户层
  2. 接口层
  3. 内核层
  4. 硬件层

网卡开始是与 e1000 等原生的网卡驱动绑定,当用户层程序执行解绑以及绑定命令,通过 sysfs 将消息发送至内核层后,网卡与 igb_uio 驱动进行了绑定。此时内核层 UIO 接管了网卡,并为用户层 PMD 提供了服务接口。

相关阅读:

原文地址:https://www.cnblogs.com/hzcya1995/p/13309549.html