
DPDK
背景
1.传统的收发报文方式都必须采用硬中断来做通讯,每次硬中断大约消耗100微秒,这
还不算因为终止上下文所带来的Cache Miss。 轮询模式驱动(PMD)
概念
PMD由用户空间的特定的驱动程序提供的API组成,用于对设备和它们相应的队列进行
设置。
特点 去除中断,避免内核态和用户态内存拷贝,减少系统开销,从而提升I/O吞吐能力
2.数据必须从内核态用户态之间切换拷贝带来大量CPU消耗,全局锁竞争。 在用户态进行数据处理
3.收发包都有系统调用的开销。
Ring Queue
针对单个或多个数据包生产者、单个数据包消费者的出入队列提供无锁机制,有效减少
系统开销
HUGEPAGE
如果有多个核可能需要同时访问一个网卡,那DPDK中会为每个核准备一个单独的接收
队列/发送队列,这样避免了竞争,也避免了cache一致性问题。
利用内存大页HUGEPAGE降低TLB(Translation Lookaside Buffer) miss,利用内存多
通道交错访问提高内存访问有效带宽,降低访存开销
4.内核工作在多核上,为可全局一致,即使采用Lock Free,也避免不了锁总线、内存
屏障带来的性能损耗。
流分类(Flow Classificatio) 为N元组匹配和LPM(最长前缀匹配)提供优化的查找算法
多队列实现
通过将网卡的某个接收队列分配给某个核,从该队列中收到的所有报文都应当在该指定
的核上处理结束,不同的核操作不同的队列。
2种方式
RSS(Receive Side Scaling,接收方扩展)机制:根据关键字,比如根据UDP的四元
组<srcIP><dstIP><srcPort><dstPort>进行哈希
Flow Director机制:可设定根据数据包某些信息进行精确匹配,分配到指定的队列与
CPU核
data buffer
DPDK将内存封装在Mbuf结构体内,Mbuf主要用来封装网络帧缓存,所有的应用使用
Mbuf结构来传输网络帧
对网络帧封装和处理时,将网络帧元数据和帧本身存放在固定大小的同一段缓存中,网
络帧元数据的一部分内容由DPDK的网卡驱动写入
网络包的分析和处理
当网络数据包(帧)被网卡接收后,DPDK网卡驱动将其存储在一个高效缓冲区中,并
在MBUF缓存中创建MBUF对象与实际网络包相连,对网络包的分析和处理都会基于该
MBUF
必要的时候才会访问缓冲区中的实际网络包
多线程
DPDK线程基于pthread接口创建,属于抢占式线程模型,受内核调度支配。
通过在多核设备上创建多个线程,每个线程绑定到单独的核上,减少线程调度的开销,
以提高性能。
控制线程一般绑定到MASTER核上,接受用户配置,并传递配置参数给数据线程等;数
据线程分布在不同核上处理数据包。
数据包转发模型
运行至完成(run-to-completion)模型
特点
同步模型
每个报文的生命周期只能在一个线程中出现,每个物理核都负责处理整个报文的生命周
期从RX到TX。
每个指派给DPDK的逻辑核心执行如下所示的循环
1.通过PMD接收用API来提取输出数据包
2.根据转发,一一处理收到的数据包
3.通过PMD发送用API发送输出数据包
管道(pipeline)模型
特点
异步模型:有的逻辑核心只执行数据包提取,而有的只执行处理,收到的数据包在这些
逻辑核心之间通过环来传递
提取核心执行循环
1.通过PMD接收用API来提取输出数据包
2.通过队列提供数据包给处理核心
处理核心执行循环
1.从队列中提取数据包
2.根据重传(如果被转发)处理数据包
概念
数据平面开发套件(DPDK [1] ,Data Plane Development Kit)是由6WIND,Intel等多家
公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以
极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。
主要目的
在数据平面应用中为快速的数据包处理提供一个简单而完善的架构。在理解此工具集之
后,开发人员可以以此为基础进行新的原型设计,或简单地为我所用。
工作环境
DPDK的环境抽象层向应用与函数库隐藏了底层环境的细节,因而能扩展到任何处理器
上使用
操作系统
linux
FreeBSD
DPDK架构
优点
性能高
用户态开发,一旦程序崩溃,不至于导致内核完蛋,带来更高的健壮性
缺点
无网络协议栈
开发困难,周期长
框架
核心库Core Libs
环境抽象层(EAL, Environment Abstraction Layer)
功能
主要负责对计算机底层资源(如硬件和内存空间)的访问,并对提供给用户的接口实施
了实现细节的封装。其初始化例程决定了如何分配这些资源(PCI设备、计时器、控制
台等
EAL提供的典型服务
加载和启动DPDK:DPDK及其应用程序会被链接为单一应用,因此需要通过某种方式
进行加载DPDK。
CPU功能识别:在运行时确定CPU是否支持特定功能,确定当前CPU是否支持编译产
生的二进制指令集。
核关联/分配过程:EAL提供了将执行单元分配给特定核并创建执行实例的机制。
预留系统内存:EAL为预留不同的内存区域提供便利,例如用于设备交互的物理内存区
域。
抽象PCI地址:EAL提供了访问PCI地址空间的接口。
中断处理:向特定中断源注册/注销回调的接口。
跟踪和调试功能:日志、堆栈转储等。
实用的功能:libc中所没有提供的自旋锁和原子计数器。
时钟功能:用于设置/删除在特定时间运行的回调函数接口。
data manager
Malloc Library 提供分配任意大小内存的API。
Ring Library
提供对一种特殊的链表队列的管理,具有先进先出、定长、无锁、并发入/出队等特
性。
优点:工作更快,实现简单,适用于块数据的入/出队
Mempool Library
内存池用于分配固定大小的对象。在DPDK中内存池用名字区分,并用环来存储未使用
的对象
Mbuf Library 用于分配和释放缓冲区给DPDK应用来存储缓存信息,使用上述的内存池来存储。
Extns(Packet manager)
Packet Framework
1.为建造复杂的数据包处理管道提供标准方法
2.为相同的管道程序块提供在纯软件和硬件加速这两种实现间切换的能力
3.在灵活性和性能间找到最佳的折中方案
4.提供逻辑上类似于Open Flow(SDN核心技术)的架构。
Packet Distributor Library
用于流量的动态负载均衡问题。使用时,使用中的逻辑核心会被考虑为两种角色:其一
是一个分配器核心,负责负载均衡或数据包分配;其二是一群工人核心,负责从分配器
接收数据包并对它们进行处理。
缺点:定长、环多导致内存占用增加
PMD Library
提供全用户态驱动,以便通过轮询和线程绑定得到极高网络吞吐,支持各种本地和虚拟
网卡。
Classify Library 支持精确匹配,最长匹配和通配符匹配,提供常用包处理的查表操作。
Qos Library 提供网络服务质量相关组件,限速和调度。
KNI(Kernel NIC Interface)
为了让数据包重入内核协议栈,通过创建虚拟设备用于收发报文以达到利用内核本身已
实现协议的目的
UIO:user-space drivers
作用
作为高并发大流量网络开发框架的DPDK,能够避免内核中断爆炸和大量数据拷贝的方
法,在用户空间能够直接和硬件进行交互。
原理 将硬件操作映射到用户空间的kernel bypass方案
实现
1.开发运行在内核的UIO模块,因为硬中断只能在内核处理
2.read感知中断,通过/dev/uioX读取中断
3.通过mmap和外设共享内存
驱动的作用
处理硬件产生的中断以及存取硬件的内存区域数据。
内核态的职责
分配和记录设备需要的资源和注册uio设备
使能设备
申请资源
读取并记录配置信息
注册uio设备
必须*在内核空间实现的小部分中断应答函数
用户态职责
获取中断事件(read/poll)
处理中断(读写数据)
igb_uio分析
注册一个pci设备,在DPDK工具dpdk_nic_bind.py绑定NIC的时候这个驱动会probe到
这个设备,进行相关配置。之后会注册一个UIO设备,probe函数会将记录设备的资源
比如PCI设备BAR空间的物理地址、大小等信息记录下来传给用户态。
DPDK的高性能代码实现
Hugepage
如果有多个核可能需要同时访问一个网卡,那DPDK中会为每个核准备一个单独的接收
队列/发送队列,这样避免了竞争,也避免了cache一致性问题。
2M或1G字节
SNA(Shared-nothing Architecture) 无共享架构,尽量避免全局共享,带来全局竞争,失去横向扩展的能力。
SIMD(Single Instruction Multiple Data) DPDK采用批量同时处理多个包,再用向量编程,一个周期内对所有包进行处理
Burst收发包
Burst为一次完成多个数据包的收发,通过把收发包复杂的处理过程进行分解,打散成
不同的相对较小的处理阶段,把相邻数据访问、相似的数据运算集中处理,尽可能减少
对内存或者低一级的处理器缓存的访问次数
平台优化配置
硬件 网卡多队列收发包,支持收包RSS时分发进多个队列
软件
关闭CPU以及设备的省电模式
让内存运行在所支持的最高频率上
内核初始化时设置好大页
增加内核启动参数,预先指定DPDK使用的逻辑核,不被操作系统调度
DPDK参数配置
收包队列长度,即每个收包队列分配的收包描述符个数(128)
发包队列长度,即每个发包队列分配的发包描述符个数(512)
收包队列可释放描述符数量阈值,DPDK驱动程序并没有每次收包都更新收包队列尾部
索引寄存器,而是在可释放的收包描述符数量达到一个阈值时更新,设置合理,可以减
少没有必要的过多收包队列尾部索引寄存器的访问。默认值为32.
发包队列可释放描述符数量阈值,通过将回写标记设置在一定间隔的发包描述符上,减
少不必要的回写次数,改善性能,默认为32.
发包描述符释放阈值,当用来重新配置的发包描述符数量少于阈值时,才会启动描述符
和Mbuf释放动作,设置太大释放频繁,影响性能,设置太小可用描述符少,容易丢
包,默认值为32.
...
评论