DPDK 背景和优势,赶紧学起来运用吧
一.背景
1.传统的收发报文方式都必须采用硬中断来做通讯,每次硬中断大约消耗 100 微秒,这还不算因为终止上下文所带来的 Cache Miss。
2.数据必须从内核态用户态之间切换拷贝带来大量 CPU 消耗,全局锁竞争。
3.收发包都有系统调用的开销。
4.内核工作在多核上,为可全局一致,即使采用 Lock Free,也避免不了锁总线、内存屏障带来的性能损耗。
5.从网卡到业务进程,经过的路径太长,有些其实未必要的,例如 netfilter 框架,这些都带来一定的消耗,而且容易 Cache Miss
1、传统服务器可能有如下潜在的问题
异步模式的弊端
在没有请求到来的时候,线程将会休眠,当数据到来时,将由操作系统唤醒对应的线程,也就是说内核需要负责线程间频繁的上下文切换,我们是在依靠操作系统调度系统来服务网络包的调度。
协议栈的扩展性
协议栈中嵌入了大量用于对接的接口,如果能让应用程序直接接管网络数据包处理、内存管理以及 CPU 调度,那么性能可以得到一个质的提升。为了达到这个目标,第一个要解决的问题就是绕过 Linux 内核协议栈
多核的可扩展性
在多个 CPU 核心上平行扩展:尽量让每个核维护独立数据结构;使用原子操作来避免冲突;使用无锁数据结构避免线程间相互等待;设置 CPU 亲缘性,将操作系统和应用进程绑定到特定的内核上,避免 CPU 资源竞争;在 NUMA 架构下尽量避免远端内存访问
内存的可扩展性
内存的访问速度永远也赶不上 cache 和 cpu 的频率,为了能让性能平行扩展,最好是少访问。
减少访存次数来避免 cachemisses 是我们设计的目标。
指针不要随意指向任意内存地址,因为这样每一次指针的间接访问可能会导致多次 cache misses,最好将需要访问的数据放到一起,方便一次性加载到 cache 中使用。按照 4K 页来计算,32G 的数据需要占用 64M 的页表,使得页表甚至无法放到 cache 中,这样每次数据访问可能需要两次访问到内存,因此建议使用 2M 甚至 1G 的大页表来解决这个问题。
解决方案
控制层留给 Linux 做,其它数据层全部由应用程序来处理。减少系统调度、系统调用、系统中断,上下文切换等
摒弃 Linux 内核协议栈,将数据包传输到用户空间定制协议栈
使用多核编程技术替代多线程,将 OS 绑在指定核上运行
针对 SMP 系统,使 CPU 尽量使用所在 NUMA 系统节点的内存,减少内存刷写
使用大页面,减少访问
采用无锁技术解竞争
概念:
DPDK 应用程序是运行在用户空间上利用自身提供的数据平面库来收发数据包,绕过了 Linux 内核协议栈对数据包处理过程。Linux 内核将 DPDK 应用程序看作是一个普通的用户态进程,包括它的编译、连接和加载方式和普通程序没有什么两样。
传统 linux 网络层:
硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完毕通知用户层
用户层收包-->网络层--->逻辑层--->业务层
dpdk 网络层:
硬件中断--->放弃中断流程
用户层通过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层
linux 协议栈:
DPDP 的优势:
减少了中断次数。
减少了内存拷贝次数。
绕过了 linux 的协议栈,进入用户协议栈,用户获得了协议栈的控制权,能够定制化协议栈降低复杂度
DPDK 的劣势:
内核栈转移至用户层增加了开发成本.
低负荷服务器不实用,会造成内核空转
评论