阿里云用到的DPDK(分析原理)以及学习路线

前言:随着互联网的高速发展,云产业的快速突起,基础架构网络逐渐偏向基于通用计算平台或模块化计算平台的架构融合,来支持多样化的网络功能,传统的PC机器在分布式计算平台上的优点更为明显。在这些针对海量数据处理或海量用户的服务场景,高性能编程显得尤其重要。

image

1、背景分析

前10年中,网络程序性能优化的目标主要是为了解决C10K问题,其研究主要集中在如何管理数万个客户端并发链接,各类I/O框架下如何进行性能优化,以及操做系统参数的一些优化。当前,解决C10K问题的服务器已经很是多。Nginx和Lighttpd两款很是优秀的基于事件驱动的web服务框架,Tornado和Django则是基于python开发的非阻塞的web框架这些软件使得C10K已经再也不是问题了。python

从总体上看 为了知足日益增加的需求主要采用分布式集群来分担负荷,应对大量的用户请求。
在这里插入图片描述
(1)集群
从结构上来看一个节点的服务器框架包含:
•网络模块
•事件驱动模块
•隔离,多核业务分发模块
•业务层
•在单个节点上,核的使用来看,主要包括
•单线程服务器 优势是无竞争,缺点是没有充分利用系统资源
•多进程模型 隔离性好,利用了系统更多的资源,缺点是进程间资源共享难
•多线程模型 充分利用系统资源,竞争须要当心处理linux

(2)需求分析web

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刚好为咱们提供了解决问题的脚手架。
image

2、DPDK简介

Intel® DPDK全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持,它不一样于Linux系统以通用性设计为目的,而是专一于网络应用中数据包的高性能处理。目前已经验证能够运行在大多数Linux操做系统上,包括FreeBSD 9.二、Fedora release1八、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)网络模块
DPDK对从内核层到用户层的网络流程相对传统网络模块进行了特殊处理,下面对传统网络模块结构和DPDK中的网络结构作对比。
(2)传统linux网络层
硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完毕通知用户层 用户层收包-->网络层--->逻辑层--->业务层
(3)DPDK网络层
硬件中断--->放弃中断流程 用户层经过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层
1.DPDK优点:

  • 减小了中断次数。
  • 减小了内存拷贝次数。
  • 绕过了linux的协议栈,进入用户协议栈,用户得到了协议栈的控制权,可以定制化协议栈下降复杂度。

2.DPDK劣势:

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

三、具体分析

拦截中断,不触发后续中断和流程流程,绕过协议栈。
以下所示,经过UIO可以重设内核中终端回调行为从而绕过协议栈后续的处理流程:
image.png

4.Trigger

无拷贝收发包,减小内存拷贝开销 如图所示
dpdk的包所有在用户空间使用内存池管理。
内核空间与用户空间的内存交互不用进行拷贝,只作控制权转移。

image.png

5.packet trans

协议栈库 dpdk为用户提供了部分协议处理封装,使用户能轻松定制化协议栈。
(4)内存管理

1.hugepage技术

Linux系统的内存管理依赖于存储器上,以下所示 Linux在内存管理中采用受保护的虚拟地址模式,在代码中地址分为3类:逻辑地址、线性地址、物理地址。程序使用具体内存简单说就是逻辑地址经过分段机制映射转化为线性地址,而后线性地址经过分页机制映射转化为物理地址的过程,而在实际使用中,仅将线性地址映射为物理地址的过程当中,须要从内存中读取至少四次页目录表(Page Directory)和页表 (Page Table),为了加快内核读取速度,CPU在硬件上对页表作了缓存,就是TLB。 线性地址先从TLB获取高速缓存内存,若是不存在就从内存表获取,若是有直接的映射,直接从内存读取,没有则产生缺页中断,重新分配物理内存,或者从硬盘上将swap读取。具体图示以下:

image.png

普通页大小是每一个4K,若是是4K页的寻址以下,使用物理内存时须要多级查找才能找到对应的内存。
image.png

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尽可能使用靠近其所在节点的内存,避免访问远程内存影响效率。
image.png

(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,内存,日志等系统的初始化
•从核启动后等待主核初始化完毕后挂载业务处理入口
•从核运行业务代码
image.png

(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.`

image.png

3、扩展

(1)热更新

DPDK在多线程管理上隔离性至关好,主核和从核经过管道进行命令交互,主核能够轻松的将业务下发给从核,所以能够很容易的利用这个特色作业务接口热更新支持。

(2)底层转发

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