乐趣区

关于linux:腾讯阿里工程师所热衷的DPDK到底是个什么东西

高性能网络技术

随着云计算产业的异军突起,网络技术的不断创新,越来越多的网络设备基础架构逐渐向基于通用处理器平台的架构方向交融,从传统的物理网络到虚构网络,从扁平化的网络结构到基于 SDN 分层的网络结构,无不体现出这种翻新与交融。

这在使得网络变得更加可管制和老本更低的同时,也可能反对大规模用户或应用程序的性能需求,以及海量数据的解决。究其原因,其实是高性能网络编程技术随着网络架构的演进一直冲破的一种必然结果。

C10K 到 C10M 问题的演进

现在,关注的更多是 C10M 问题(即单机 1 千万个并发连贯问题)。很多计算机领域的大佬们从硬件上和软件上都提出了多种解决方案。从硬件上,比如说,当初的相似很多 40Gpbs、32-cores、256G RAM 这样配置的 X86 服务器齐全能够解决 1 千万个以上的并发连贯。

然而从硬件上解决问题就没多大意思了,首先它老本高,其次不通用,最初也没什么挑战,无非就是堆砌硬件而已。所以,抛开硬件不谈,咱们看看从软件上该如何解决这个世界难题呢?

这里不得不提一个人,就是 Errata Security 公司的 CEO Robert Graham,他在 Shmoocon 2013 大会上很奇妙地解释了这个问题。有趣味能够查看其 YouTube 的演进视频:C10M Defending The Internet At Scale。

他提到了 UNIX 的设计初衷其实为电话网络的控制系统而设计的,而不是个别的服务器操作系统,所以,它仅仅是一个数据负责数据传送的零碎,没有所谓的管制层面和数据层面的说法,不适宜解决大规模的网络数据包。最初他得出的论断是:

OS 的内核不是解决 C10M 问题的方法,恰恰相反 OS 的内核正式导致 C10M 问题的关键所在。

为什么这么说?基于 OS 内核的数据传输有什么弊病?

1、中断解决。当网络中大量数据包到来时,会产生频繁的硬件中断请求,这些硬件中断能够打断之前较低优先级的软中断或者零碎调用的执行过程,如果这种打断频繁的话,将会产生较高的性能开销。

2、内存拷贝。失常状况下,一个网络数据包从网卡到应用程序须要通过如下的过程:数据从网卡通过 DMA 等形式传到内核开拓的缓冲区,而后从内核空间拷贝到用户态空间,在 Linux 内核协定栈中,这个耗时操作甚至占到了数据包整个解决流程的 57.1%。

3、上下文切换。频繁达到的硬件中断和软中断都可能随时抢占零碎调用的运行,这会产生大量的上下文切换开销。另外,在基于多线程的服务器设计框架中,线程间的调度也会产生频繁的上下文切换开销,同样,锁竞争的耗能也是一个十分重大的问题。

4、局部性生效。现在支流的处理器都是多个外围的,这意味着一个数据包的解决可能跨多个 CPU 外围,比方一个数据包可能中断在 cpu0,内核态解决在 cpu1,用户态解决在 cpu2,这样跨多个外围,容易造成 CPU 缓存生效,造成局部性生效。如果是 NUMA 架构,更会造成跨 NUMA 拜访内存,性能受到很大影响。

5、内存治理。传统服务器内存页为 4K,为了进步内存的访问速度,防止 cache miss,能够减少 cache 中映射表的条目,但这又会影响 CPU 的检索效率。

综合以上问题,能够看出内核自身就是一个十分大的瓶颈所在。那很显著解决方案就是想方法绕过内核。

解决方案探讨

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

1、管制层和数据层拆散。将数据包解决、内存治理、处理器调度等工作转移到用户空间去实现,而内核仅仅负责局部控制指令的解决。这样就不存在上述所说的零碎中断、上下文切换、零碎调用、系统调度等等问题。

2、应用多核编程技术代替多线程技术,并设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,缩小彼此之间调度切换。

3、针对 NUMA 零碎,尽量使 CPU 核应用所在 NUMA 节点的内存,防止跨内存拜访。

4、应用大页内存 代替一般的内存,缩小 cache-miss。

5、采纳无锁技术 解决资源竞争问题。

经很多前辈先驱的钻研,目前业内曾经呈现了很多优良的集成了上述技术计划的高性能网络数据处理框架,如 6wind、windriver、netmap、dpdk 等,其中,Intel 的 dpdk 在泛滥计划怀才不遇,一骑绝尘。

dpdk 为 Intel 处理器架构下用户空间高效的数据包解决提供了库函数和驱动的反对,它不同于 Linux 零碎以通用性设计为目标,而是专一于网络应用中数据包的高性能解决。

也就是 dpdk 绕过了 Linux 内核协定栈对数据包的处理过程,在用户空间实现了一套数据立体来进行数据包的收发与解决。在内核看来,dpdk 就是一个一般的用户态过程,它的编译、连贯和加载形式和一般程序没有什么两样。


感兴趣的敌人能够进群 973961276 一起聊聊技术吹吹牛,每周都会有几次抽奖送专业书籍的
流动,奖品不甚值钱,但能够来搏个彩头[doge]

感觉文字乏味的敌人能够看看这个视频 >> 阿里云用 DPDK 如何解决千万级流量并发

不足我的项目实战经验和想跳槽涨薪或是自我晋升的敌人看这里 >>c/c++ 我的项目实战 / 后盾服务器开发高级架构师

dpdk 的冲破

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

传统 Linux 内核网络数据流程:

Copy

硬件中断 ---> 取包散发至内核线程 ---> 软件中断 ---> 内核线程在协定栈中解决包 ---> 处理完毕告诉用户层 用户层收包 --> 网络层 ---> 逻辑层 ---> 业务层

dpdk 网络数据流程:

Copy

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

上面就具体看看 dpdk 做了哪些冲破?

UIO(用户空间的 I/O 技术)的加持。

dpdk 可能绕过内核协定栈,实质上是得益于 UIO 技术,通过 UIO 可能拦挡中断,并重设中断回调行为,从而绕过内核协定栈后续的解决流程。

UIO 设施的实现机制其实是对用户空间裸露文件接口,比方当注册一个 UIO 设施 uioX,就会呈现文件 /dev/uioX,对该文件的读写就是对设施内存的读写。除此之外,对设施的管制还能够通过 /sys/class/uio 下的各个文件的读写来实现。

内存池技术

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

大页内存治理

dpdk 实现了一组大页内存调配、应用和开释的 API,下层利用能够很方便使用 API 申请应用大页内存,同时也兼容一般的内存申请。

无锁环形队列

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

poll-mode 网卡驱动

DPDK 网卡驱动齐全摈弃中断模式,基于轮询形式收包,防止了中断开销。

NUMA

dpdk 内存调配上通过 proc 提供的内存信息,使 CPU 外围尽量应用凑近其所在节点的内存,防止了跨 NUMA 节点近程拜访内存的性能问题。

CPU 亲和性

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

多核调度框架

dpdk 基于多核架构,个别会有主从核之分,主核负责实现各个模块的初始化,从核负责具体的业务解决。

除了上述之外,dpdk 还有很多的技术冲破,能够用上面这张图来概之。

dpdk 的利用

dpdk 作为优良的用户空间高性能数据包减速套件,当初曾经作为一个“胶水”模块被用在多个网络数据处理计划中,用来进步性能。如下是泛滥的利用。

数据面(虚构交换机):

OVS

Open vSwitch 是一个多核虚构交换机平台,反对规范的治理接口和凋谢可扩大的可编程接口,反对第三方的管制接入。

https://github.com/openvswitch/ovs

VPP

VPP 是 cisco 开源的一个高性能的包解决框架,提供了 替换 / 路由 性能,在虚拟化环境中,使它能够当做一个虚构交换机来应用。在一个类 SDN 的解决框架中,它往往充当数据面的角色。经钻研表明,VPP 性能要好于 ovs+dpdk 的组合,但它更实用于 NFV,适宜做特定性能的网络模块。

https://wiki.fd.io/view/VPP

Lagopus

Lagopus 是另一个多核虚构替换的实现,性能和 OVS 差不多,反对多种网络协议,如 Ethernet,VLAN,QinQ,MAC-in-MAC,MPLS 和 PBB,以及隧道协定,如 GRE,VxLan 和 GTP。

https://github.com/lagopus/lagopus/blob/master/QUICKSTART.md

Snabb

Snabb 是一个简略且疾速的数据包解决工具箱。

https://github.com/SnabbCo/snabbswitch/blob/master/README.md

数据面(虚构路由器):

OPENCONTRAIL

一个集成了 SDN 控制器的虚构路由器,当初多用在 OpenStack 中,联合 Neutron 为 OpenStack 提供一站式的网络反对。

http://www.opencontrail.org/

CloudRouter

一个分布式的路由器。

https://cloudrouter.org/

用户空间协定栈

mTCP

mTCP 是一个针对多核零碎的高可扩展性的用户空间 TCP/IP 协定栈。

https://github.com/eunyoung14/mtcp/blob/master/README

IwIP

IwIP 针对 RAM 平台的精简版的 TCP/IP 协定栈实现。

http://git.savannah.gnu.org/cgit/lwip.git/tree/README

Seastar

Seastar 是一个开源的,基于 C++ 11/14 feature,反对高并发和低提早的异步编程高性能库。

http://www.seastar-project.org/

f-stack

腾讯开源的用户空间协定栈,移植于 FreeBSD 协定栈,粘合了 POSIX API,下层利用(协程框架,Nginx,Redis),纯 C 编写,易上手。

https://github.com/f-stack/f-stack

总结

dpdk 绕过了 Linux 内核协定栈,减速数据的解决,用户能够在用户空间定制协定栈,满足本人的利用需要,目前呈现了很多基于 dpdk 的高性能网络框架,OVS 和 VPP 是罕用的数据面框架,mTCP 和 f-stack 是罕用的用户态协定栈。很多大公司都在应用 dpdk 来优化网络性能。

退出移动版