关于linux:阿里云用到的DPDK分析原理以及学习路线

37次阅读

共计 6263 个字符,预计需要花费 16 分钟才能阅读完成。

前言:随着互联网的高速倒退, 云产业的疾速突起,基础架构网络逐步偏差基于通用计算平台或模块化计算平台的架构交融,来反对多样化的网络性能,传统的 PC 机器在分布式计算平台上的劣势更为显著。在这些针对海量数据处理或海量用户的服务场景,高性能编程显得尤为重要。

一、背景剖析

前 10 年中,网络程序性能优化的指标次要是为了解决 C10K 问题,其钻研次要集中在如何治理数万个客户端并发连贯,各种 I / O 框架下如何进行性能优化,以及操作系统参数的一些优化。以后,解决 C10K 问题的服务器曾经十分多。Nginx 和 Lighttpd 两款十分优良的基于事件驱动的 web 服务框架,Tornado 和 Django 则是基于 python 开发的非阻塞的 web 框架这些软件使得 C10K 曾经不再是问题了。

从整体上看 为了满足日益增长的需要次要采纳分布式集群来分担负荷, 应答大量的用户申请。
在这里插入图片形容
(1) 集群
从构造上来看一个节点的服务器框架蕴含:
•网络模块
•事件驱动模块
•隔离,多核业务散发模块
•业务层
•在单个节点上, 核的应用来看,次要包含
•单线程服务器 长处是无竞争,毛病是没有充分利用系统资源
•多过程模型 隔离性好,利用了零碎更多的资源, 毛病是过程间资源共享难
•多线程模型 充分利用系统资源,竞争须要小心解决

(2)需要剖析

1.dpdk PCI 原理与 testpmd/l3fwd/skeletion

2.kni 数据流程

3.dpdk 实现 dns

4.dpdk 高性能网关实现

5. 半虚拟化 virtio/vhost 的减速
(3) 综合剖析
•在应答网络密集型的微小数据量时,个别抉择是横向扩大节点,然而节点的增多会变相的减少设施老本和技术危险,且当集群节点到肯定的量后,节点之间的交互老本自身就会成为瓶颈。
•在特定场合下,譬如嵌入式设施上的后盾服务,服务器不可能搭建集群。

因而晋升服务器自身性能同样重要。
(4)具体分析

传统服务器可能有上面的潜在问题

•异步模式的弊病
个别咱们应用 epoll 来高效的解决网络读写事件。在基于多线程的服务器设计框架中,在没有申请到来的时候,线程将会休眠,当数据到来时,将由操作系统唤醒对应的线程,也就是说内核须要负责线程间频繁的上下文切换,咱们是在依附操作系统调度零碎来服务网络包的调度。在网络负载很大的场景下只会造成核满转且一直互相切换,进一步减少负荷. 那么就须要回到最原始的形式,应用轮询形式来实现所有操作,来晋升性能。

•协定栈的扩展性
Linix 诞生之初就是为电话电报管制而设计的,它的管制立体和数据转发立体没有拆散,不适宜解决大规模网络数据包。并且为了全面的反对用户空间的各个性能,协定栈中嵌入了大量用于对接的接口, 如果能让应用程序间接接管网络数据包解决、内存治理以及 CPU 调度,那么性能能够失去一个质的晋升。为了达到这个指标,第一个要解决的问题就是绕过 Linux 内核协定栈,因为 Linux 内核协定栈性能并不是很优良,如果让每一个数据包都通过 Linux 协定栈来解决,那将会十分的慢。像 WindRiver 和 6 Wind Gate 等公司自研的内核协定栈声称比 LinuxUDP/TCP 协定栈性能至多进步 500% 以上,因而能不必 Linux 协定栈就不必。不必协定栈的话当然就须要本人写驱动了,应用程序间接应用驱动的接口来收发报文。PF_RING,Netmap 和 intelDPDK 等能够帮忙你实现这些工作,并不需要咱们本人去破费太多工夫。Intel 官网测试文档给出了一个性能测试数据,在 1S Sandbridge-EP 8*2.0GHzcores 服务器上进行性能测试,不必内核协定栈在用户态下吞吐量可高达 80Mpps(每个包解决耗费大概 200 cpuclocks),相比之下,应用 Linux 内核协定栈性能连 1Mpps 都无奈达到。

•多核的可扩展性
多核的可扩展性对性能晋升也是十分重要的,因为服务器中 CPU 频率晋升越来越慢,纳米级工艺改良曾经是十分艰难的事件了,但能够做的是让服务器领有更多的 CPU 和外围,像国家超级计算中心的天河二号应用了超过 3w 颗 XeonE5 来进步性能。在程序设计过程中,即便在多核环境下也很快会碰到瓶颈,单纯的减少了处理器个数并不能线性晋升程序性能,反而会使整体性能越来越低。一是因为编写代码的品质问题,没有充分利用多核的并行性,二是服务器软件和硬件自身的一些个性成为新的瓶颈,像总线竞争、存储体专用等诸多影响性能平行扩大的因素。那么,咱们怎样才能让程序能在多个 CPU 外围上平行扩大:尽量让每个核保护独立数据结构;应用原子操作来防止抵触;应用无锁数据结构防止线程间互相期待;设置 CPU 亲缘性,将操作系统和利用过程绑定到特定的内核上,防止 CPU 资源竞争;在 NUMA 架构下尽量避免远端内存拜访。

•内存的可扩展性 内存的访问速度永远也赶不上 cache 和 cpu 的频率,为了能让性能平行扩大,最好是少拜访。从内存耗费来看,如果每个用户连贯占用 2K 的内存,10M 个用户将耗费 20G 内存,而操作系统的三级 cache 连 20M 都达不到,这么多并发连贯的状况下必然导致 cache 生效,从而频繁的拜访内存来获取数据。而一次内存拜访大概须要 300cpuclocks,这期间 CPU 简直被闲暇。因而缩小访存次数来 cachemisses 是咱们设计的指标。指针不要随便指向任意内存地址,因为这样每一次指针的间接拜访可能会导致屡次 cachemisses,最好将须要拜访的数据放到一起,不便一次性加载到 cache 中应用。依照 4K 页来计算,32G 的数据须要占用 64M 的页表,使得页表甚至无奈放到 cache 中,这样每次数据拜访可能须要两次拜访到内存,因而倡议应用 2M 甚至 1G 的大页表来解决这个问题。
(5)解决方案

•管制层留给 Linux 做,其它数据层全副由应用程序来解决。缩小系统调度、零碎调用、零碎中断,上下文切换等。
•摒弃 Linux 内核协定栈,将数据包传输到用户空间定制协定栈
•应用多核编程技术代替多线程,将 OS 绑在指定核上运行
•针对 SMP 零碎,使 CPU 尽量应用所在 NUMA 零碎节点的内存,缩小内存刷写
•应用大页面,缩小拜访
•采纳无锁技术解竞争而 DPDK 恰好为咱们提供了解决问题的脚手架。

二、DPDK 简介

Intel® DPDK 全称 Intel Data Plane Development Kit,是 intel 提供的数据立体开发工具集,为 Intel architecture(IA)处理器架构下用户空间高效的数据包解决提供库函数和驱动的反对,它不同于 Linux 零碎以通用性设计为目标,而是专一于网络应用中数据包的高性能解决。目前曾经验证能够运行在大多数 Linux 操作系统上,包含 FreeBSD 9.2、Fedora release18、Ubuntu 12.04 LTS、RedHat Enterprise Linux 6.3 和 Suse EnterpriseLinux 11 SP2 等。DPDK 应用了 BSDLicense,极大的不便了企业在其根底上来实现本人的协定栈或者利用。须要强调的是,DPDK 应用程序是运行在用户空间上利用自身提供的数据立体库来收发数据包,绕过了 Linux 内核协定栈对数据包处理过程。Linux 内核将 DPDK 应用程序看作是一个一般的用户态过程,包含它的编译、连贯和加载形式和一般程序没有什么两样。
相干视频:
Linux 服务器开发 - 阿里云用 DPDK 如何解决千万级流量并发 \(上 \)

Linux 服务器开发 - 阿里云用 DPDK 如何解决千万级流量并发 \(中 \)

Linux 服务器开发 - 阿里云用 DPDK 如何解决千万级流量并发 \(下 \)

次要有以下几个外围:
1、网络层模块
2、内存治理模块
3、内核治理模块

(1)网络模块
DPDK 对从内核层到用户层的网络流程绝对传统网络模块进行了非凡解决,上面对传统网络模块构造和 DPDK 中的网络结构做比照。
(2) 传统 linux 网络层
硬件中断 ---> 取包散发至内核线程 ---> 软件中断 ---> 内核线程在协定栈中解决包 ---> 处理完毕告诉用户层 用户层收包 --> 网络层 ---> 逻辑层 ---> 业务层
(3)DPDK 网络层
硬件中断 ---> 放弃中断流程 用户层通过设施映射取包 ---> 进入用户层协定栈 ---> 逻辑层 ---> 业务层
1.DPDK 劣势:

  • 缩小了中断次数。
  • 缩小了内存拷贝次数。
  • 绕过了 linux 的协定栈,进入用户协定栈,用户取得了协定栈的控制权,可能定制化协定栈升高复杂度。

2.DPDK 劣势:

  • 内核栈转移至用户层减少了开发成本。
  • 低负荷服务器不实用,会造成内核空转。

3、具体分析

拦挡中断,不触发后续中断和流程流程,绕过协定栈。
如下所示,通过 UIO 可能重设内核中终端回调行为从而绕过协定栈后续的解决流程:

4.Trigger

无拷贝收发包,缩小内存拷贝开销 如图所示
dpdk 的包全副在用户空间应用内存池治理。
内核空间与用户空间的内存交互不必进行拷贝,只做控制权转移。

5.packet trans

协定栈库 dpdk 为用户提供了局部协定解决封装,使用户能轻松定制化协定栈。
(4)内存治理

1.hugepage 技术

Linux 零碎的内存治理依赖于存储器上,如下所示 Linux 在内存治理中采纳受爱护的虚拟地址模式,在代码中地址分为 3 类:逻辑地址、线性地址、物理地址。程序应用具体内存简略说就是逻辑地址通过分段机制映射转化为线性地址,而后线性地址通过分页机制映射转化为物理地址的过程,而在理论应用中,仅将线性地址映射为物理地址的过程中,须要从内存中读取至多四次页目录表(Page Directory)和页表 (Page Table),为了放慢内核读取速度,CPU 在硬件上对页表做了缓存,就是 TLB。线性地址先从 TLB 获取高速缓存内存,如果不存在就从内存表获取,如果有间接的映射,间接从内存读取,没有则产生缺页中断,从新调配物理内存,或者从硬盘上将 swap 读取。具体图示如下:

一般页大小是每个 4K,如果是 4K 页的寻址如下,应用物理内存时须要多级查找能力找到对应的内存。

4K 的页表是 linux 针对个别状况得出的适合大小,然而对于非凡利用能够通过扩充页表面积进步内存应用效率。
dpdk 应用 hupage 的思维就是让程序尽量独占内存避免内存换出,扩充页表进步 hash 命中率,通过 hugage 技术扩充了该应用的页表大小,设定为更适宜高频内存应用程序的状态,取得了以下几点劣势。
1. 无需替换。也就是不存在页面因为内存空间有余而存在换入换出的问题
2. 缩小 TLB 负载。
3. 升高 page table 查问负载
2.NUMA

为了解决单核带来的 CPU 性能有余,呈现了 SMP,但传统的 SMP 零碎中,所有处理器共享系统总线,当处理器数目越来越多时,系统总线竞争加大,系统总线称为新的瓶颈。NUMA(非对立内存拜访)技术解决了 SMP 零碎可扩展性问题,已成为当今高性能服务器的支流体系结构之一。NUMA 零碎节点个别是由一组 CPU 和本地内存组成。NUMA 调度器负责将过程在同一节点的 CPU 间调度,除非负载太高,才迁徙到其它节点,但这会导致数据拜访延时增大。下图是 2 颗 CPU 反对 NUMA 架构的示意图,每颗 CPU 物理上有 4 个外围。

dpdk 内存调配上通过 proc 提供的内存信息,使 cpu 尽量应用凑近其所在节点的内存,防止拜访近程内存影响效率。

(3)内核治理模块

Affinity 是过程的一个属性,这个属性指明了过程调度器可能把这个过程调度到哪些 CPU 上。在 Linux 中,咱们能够利用 CPU affinity 把一个或多个过程绑定到一个或多个 CPU 上。CPU Affinity 分为 2 种,soft affinity 和 hard affinity。soft affinity 仅是一个倡议,如果不可避免,调度器还是会把过程调度到其它的 CPU 上。hard affinity 是调度器必须恪守的规定。为什么须要 CPU 绑定?
•减少 CPU 缓存的命中率 CPU 之间是不共享缓存的,如果过程频繁的在各个 CPU 间进行切换,须要一直的使旧 CPU 的 cache 生效。如果过程只在某个 CPU 上执行,则不会呈现生效的状况。在多个线程操作的是雷同的数据的状况下,如果把这些线程调度到一个处理器上,大大的减少了 CPU 缓存的命中率。然而可能会导致并发性能的升高。如果这些线程是串行的,则没有这个影响。
•适宜 time-sensitive 利用在 real-time 或 time-sensitive 利用中,咱们能够把零碎过程绑定到某些 CPU 上,把利用过程绑定到残余的 CPU 上。典型的设置是,把利用绑定到某个 CPU 上,把其它所有的过程绑定到其它的 CPU 上。
(4)核治理构造

dpdk 启动时会建设会剖析零碎的逻辑核属性建设映射表并对立治理, 每个核次要属性如下:

每个核属性包含逻辑核 id,硬核 id,numa 节点 id。dpdk 会依据零碎默认状态生成一一绑定的映射表,用户能够依据需要更改映射表,后续 dpdk 框架会依据该映射表进行核绑定。

`class core{

lcore_id;           // 逻辑核 id
core_id;            // 硬核 id
socket_id;         //NUMA 节点 id

}
class core coremap[] // 所有逻辑核的映射表 `

(5)多核调度框架
•服务器启动时选取一个逻辑核做主核
•而后启动其余核做从核
•所有线程都依据映射表做核绑定
•管制核次要实现 pci,内存,日志等零碎的初始化
•从核启动后期待主核初始化结束后挂载业务解决入口
•从核运行业务代码

(6)竞争解决
•多线程在构建服务器时经常要解决竞争问题,dpdk 提供了反对多个线程操作的无锁循环队列来躲避抵触,替换数据。
•数据包等须要大量重复使用的构造能够互相隔离,线程持有独立的可用内存池。
(七) 性能剖析
Seastar 是开源的 C ++ 框架用于构建在古代硬件上构建高性能的服务器利用。该框架基于 DPDK,利用 Seastar 开发的利用能够运行在 Linux 或 OSv 之上。

上面是 seastar 的介绍以及利用其开发的内存服务器与其余服务器的比照,可见 dpdk 性能绝对传统框架有肯定劣势,且在网络密集型的场景下成果很好。
`Seastar uses a shared-nothing model that shards all requests onto individual cores.
Seastar offers a choice of network stack, including conventional Linux networking for ease of development, DPDK for fast user-space networking on Linux, and native networking on OSv.
an advanced new model for concurrent applications that offers C++ programmers both high performance and the ability to create comprehensible, testable high-quality code.
a design for sharing information between CPU cores without time-consuming locking.`

三、扩大

(1)热更新

DPDK 在多线程治理上隔离性相当好,主核和从核通过管道进行命令交互,主核能够轻松的将业务下发给从核,因而能够很容易的利用这个特点做业务接口热更新反对。

(2)底层转发

如下图所示,大部分程序交互时是在传输层及以上,但 DPDK 从二层切入,在构建集群须要大规模转发数据时能够应用三层转发,这样将使数据包转发升高 1 层协定栈的开销。

正文完
 0