C10K C10M 经过DPDK+用户态协议栈来进行内核旁路来提高网络性能

2021年11月23日 阅读数:4
这篇文章主要向大家介绍C10K C10M 经过DPDK+用户态协议栈来进行内核旁路来提高网络性能,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

千万并发链接下,如何保障网络性能? https://mp.weixin.qq.com/s/lDhCoLN0mknquJcO15Fd2Qlinux

千万并发链接下,如何保障网络性能?

图片

 

图片

 

过去几十年互联网呈爆发式的增加,内容的丰富以及层出不穷的DDoS攻击等,对网络性能提出了极大的挑战,也一样促进了网络基础设施的快速发展。运营商的带宽愈来愈大,CPU/网卡等硬件的性能也会愈来愈强。但在很长时间内,软件的性能提高落后于硬件的性能提高,并严重限制了应用程序的性能,大部分时间不得不依靠堆机器来应对,形成了大量的资源浪费和成本提升。git

 

随着软件的不断发展,在新世纪的第一个10年时,经过多线程和事件驱动(kqueue/epoll等)解决了C10K的问题。可是在第二个10年却不堪重负,亟需新的解决方案来应对网络流量的增加。github

 

好比腾讯云对外提供的HttpDNS服务每隔几个月请求量都会翻倍,对高性能的网络处理和用户态协议栈都有强烈的需求。HttpDNS早期使用的内核协议栈只能作到单机不到10万QPS的TCP短链接服务。随着技术的进步和发展,如REUSEPORT等,后续内核协议栈也能够作到几十万QPS了,但依然存在很是大的横向扩展瓶颈。基于这样的瓶颈下,腾讯云迫切须要一个高性能的网络服务框架,因此选择了经过DPDK+用户态协议栈来进行内核旁路来提高网络性能算法

 

Robert David Graham在2013年针对C10M的演讲中,对于如何达到千万并发链接,最主要的观点就是内核才是阻碍性能提高的问题,咱们应该绕过内核(kernel by pass,内核旁路)以及大量其它的技术优化,如轮询、零拷贝、Hugepage等。编程

 

Linux内核后续引入的eBPF和XDP一样可以大幅提高网络性能,可是其提高性能的本质依然是绕过内核,目前还未能对Intel DPDK生态形成实质的冲击,尤为是对高内核版本和网卡驱动的依赖,严重限制了在企业的使用推广。缓存

 

在这次演讲以前,相关的技术已经获得了必定的应用,如演讲中提到的PF_RING、Netmap、IntelDPDK等数据驱动,腾讯云DNSPod在2012年就已经完成了相关软硬件的调研选型工做,并最终选择DPDK(此时还没有开源)实现了新一代的权威DNS服务器达到了单10GE 1100万QPS的性能,大幅提高了DNS的常规解析和抗攻击能力。可是确实直到该演讲出现后,相关技术才在业界获得了大规模的开发应用,尤为是从中脱颖而出的DPDK,几乎成了高性能网络程序的标配。而咱们也是在16年的时候将权威DNS中使用DPDK的网络模块单独抽出来做为一个独立的通用的网络框架,能够复用到多个业务上提高网络性能,也就是如今的F-Stack。安全

 

 

1、F-Stack介绍及技术特色性能优化

 

F-Stack是一个全用户态的高性能的网络接入开发包,基于DPDK、FreeBSD协议栈、微线程接口等,用户只须要关注业务逻辑,简单的接入F-Stack便可实现高性能的网络服务器。将网络包进行内核旁路到应用层进行处理虽然大幅提高了网络性能,可是也没法再使用内核的网络协议栈了,这对4层如下以及简单的UDP 7层应用影响不大,可是对其余的7层应用来讲,一个成熟的用户态协议栈是必须的,因此F-Stack就是腾讯云DNSPod给出的方案。服务器

 

F-Stack是基本完整的网络编程框架,至关于用胶水粘合了了DPDK网络I/O模块、FreeBSD用户态协议栈、POSIX Like API,异步编程接口、部分上层应用等,供用户接入使用网络

 

使用纯C开发(部分第三方组件使用了C++、F-Stack进行了封装),容易上手,但也要求用户有必定的DPDK使用基础。使用BSD 2-Clause开源协议,对商业使用很是友好。那对于F-Stack都有哪些技术特色呢?接下来将继续介绍。

 

(一)多进程架构,轮询模式

 

这里是F-Stack的一个基本架构,采用多进程模型,全用户态,每一个进程与一个CPU核心、网卡收发队列进行绑定,拥有更好的内存局部性,避免缓存失效,且进程内部使用轮询模式,无锁、无调度、无上下文切换。

 

图片

 

F-Stack目前采用多进程架构,各进程拥有本身进程独立的协议栈,应用接口和应用层业务逻辑,规避了内核的多种性能瓶颈,各个进程间无数据共享,有很是好的横向扩展能力。

 

 

(二)DPDK开发套件

 

DPDK是普遍使用的数据平面开发套件,此处再也不对其自己进行过多介绍。F-Stack对DPDK版本的选用上除了初始开源版本使用了16.07版本以外,很快升级并一直保持使用DPDK的LTS版本(xx.11)版本,但通常会在最新的LTS版本发布以后数个月在dev分支进行升级支持,并在更晚以后的时间(通常1年左右)正式发布,如目前F-Stack主力稳定的1.20和1.21版本分别使用了DPDK 18.11.x和19.11.x版本,在开发分支中则支持了20.11.x版本。

 

 

(三)FreeBSD协议栈

 

F-Stack对于选用FreeBSD协议栈进行用户态移植,背后实际上是有过不少的思考和尝试的,此处仅列觉几个FreeBSD协议栈的优势,更多信息能够经过后面的F-Stack背景故事进行了解。

 

  • 协议栈功能完善,且有大量工具能够对网络进行调试分析,如sysctl、ifconfig、netstat、netgraph、ipfw、ndp等。

 

  • 能够跟进社区的改进,无需本身开发维护,有原始用户态移植可供参考,大幅减小工做量,见libplebnet和libuinet。

 

  • 相比Linux的协议栈实现复杂,FreeBSD的代码更清晰易懂;Linux遵循GPL协议开源,可能会限制部分用户的使用。

 

F-Stack目前发布版本均基于FreeBSD releng 11.0 版本,并移植了部分后续版本的patch,功能完善但也冗余(去除了部分模块未编译进F-Stack,如SCTP、IPSEC等),调试分析工具完善,运行稳定。后续则会升级到 FreeBSD releng 13.0版本,并将持续跟进社区的重大改进。

 

 

(四)POSIX兼容接口

 

F-Stack提供POSIX like接口,前缀为“ff_”,如“ff_socket”“ff_bind”等,并提供了“ff_kqueue”事件驱动接口并同时基于kqueue封装了“ff_epoll”接口,除“ff_epoll”接口的使用上与linux系统接口略有区别外,其余接口用法彻底兼容,现有程序能够作到简单改动便可接入。

 

须要注意的是,虽然接口用法彻底兼容,可是由于不少标记位在Linux和FreeBSD系统的定义并不相同,F-Stack接口内部会进行定义的转换,可是并不能保证100%支持,尤为是后续新增的标记定义,也须要持续进行更新维护。

 

POSIX like接口对原有应用的移植是友好的,而且使用上也比较安全,可是由于涉及到内存拷贝,因此性能上并不能达到最优,后续F-Stack也会提供一套独立的零拷贝API供有须要的用户选用。

 

 

(五)微线程框架

 

F-Stack应用程序必须使用异步模式接口进行编程,但也同时提供了微线程(协程)框架,能够供用户进行同步编程,异步执行。

 

微线程框架使用了同为腾讯开源的MSEC中的一部分micro_thread,须要特别注意的是微线程模块的开源协议是GPL-2.0,并非F-Stack主要的必须核心模块,对F-Stack主体开源协议并没有影响,可是若是用户以 micro_thread模块进行应用开发,则需关注开源协议可能形成的影响。

 

 

(六)应用移植

 

F-Stack目前是提供lib库接入的方式,须要与业务应用程序一块儿编译打包,并直接提供了已经移植好的Nginx和Redis应用供用户直接使用。

 

对于部分原多线程架构的应用程序,尤为是有资源共享时,为了达到更好的性能和横向扩展能力,咱们的建议是尽可能可以拆分并减小资源的共享。若是实在没法拆分,F-Stack后续也会考虑提供独立的网络I/O和协议栈模块,可是性能的降低也将不可避免。

 

 

(七)适用场景

 

这里咱们先来看下Nginx分别使用F-Stack和内核协议栈的一个性能对比,分别是短连接和长连接,须要说明的是内核协议栈也是通过了多种调优以后的测试数据,好比网卡队列、worker的CPU亲和性绑定,开启REUSEPORT 和其余内核网络参数的优化调整。

 

图片

 

图片

 

这里F-Stack对内核协议栈都有明显的提高,可是其中超过12核以后的短连接的提高尤为明显,F-Stack对大部分高并发的网络应用场景都有较好的性能优化和使用价值,其中最适合的是超大并发的TCP短连接业务场景,这也是咱们HttpDNS的主要业务场景。

 

固然,想要全面的了解F-Stack的业务应用,就必需要从其发展历史的开启来看待。

 

 

(八)F-Stack发展历史

 

目前对外开源的F-Stack已是3.0版本,1.0版本是12-13年DNSPod的权威DNS选用DPDK来提高性能时候,是一个简易的用户态TCP协议栈用来支持TCP DNS,13年上线后一直在线上持续运行,近两年已经所有升级到3.0了。

 

为了支持DNS业务的快速发展,不能缺乏一个高性能的用户态协议栈,而维护一个功能完善的TCP协议栈须要耗费大量的精力,这也是开发F-Stack 2.0和3.0的一个很重要的缘由。

 

16年的时候当时的leader拍板下,咱们放弃了继续维护1.0的协议栈,选用开源协议栈进行适配升级并对外开源,经过调研先选择了seastar(排除了MTCP、LwIP等),并在当年作了2.0版本,也作了一些应用适配,好比 HttpDNS,腾讯云动态加速CDN(DSA,如今已经合并到全站加速ECDN中)等,可是理想是美好的,现实是残酷的,虽然基于F-Stack2.0版本的HttpDNS在实验室表现堪称完美,性能优异,可扩展插件式架构等,可是在现网少许灰度运营时踩了无数坑,这和Seastar自己的使用场景是相关的,做为 ScyllaDB的组件,其主要应用场景是在内网的,并不能很好的适应外网复杂的网络环境。

 

在团队填了很多坑,也提交了多个Pull Request到Seastar后咱们发现又陷入了1.0版本的循环,因此坚持一段时间后仍是放弃了Seastar,转而从更成熟的Llinux和FreeBSD协议栈中选择了FreeBSD来开发F-Stack 3.0,也就是目前对外开源的版本。固然F-Stack 2.0的框架其实也并无彻底废弃,虽然在主要服务于外网的HttpDNS上水土不服,可是在之内网互联加速为主要场景的CDN动态加速DSA中是运行了多年才进行升级的。

 

17年上半年咱们基于DPDK和FreeBSD协议栈开发完成了F-Stack 3.0,并对外开源,并很快从新适配了HttpDNS,由于HttpDNS的请求量一直在快速增加,业务性能压力很是大,因此优先适配HttpDNS,并逐步上线对外提供服务,虽而后续也遇到了一些问题,可是都很快优化并稳定下来,到目前支撑了日请求量万亿的HttpDNS请求并保持了10倍。

 

 

(九)F-Stack开源版本历史

 

  • 2017.4.14 正式开源

  • 2017.11.27 Release 1.11

  • 2018.5.21 Release 1.12

  • 2019.11.15 Release1.13

  • 2019.11.23 Release 1.20

  • 2021.1.29 Release 1.21

     

     

2、F-Stack ROADMAP

 

目前F-Stack也一直在持续维护中,预计2021年末至2022年初将发布1.22版本,可能包含如下新特性:

 

  • DPDK 20.11,dev分支已经升级支持,相比19.11以前在编译和使用方式上有很大区别,仅支持使用meson/ninja进行编译。

 

  • FreeBSD 13.0,dev分支已经升级支持,可是目前还没有彻底稳定,依然存在一些问题,如BBR/RACK尚不能正常工做,多进程性能存在部分问题待优化,部分工具的部分功能异常(如ff_netstat对监听端口的查看等),还需进一步调试优化。

 

  • 新的零拷贝接口支持。

 

  • 原有应用一键移植支持,提供的独立的网络I/O和协议栈模块,提供相似LD_PRELOAD或其余方式简化应用移植门槛,但必定会致使性能降低。

 

  • Nginx-1.20支持。

 

  • Redis 6支持。

 

接收端网卡分流的默认方式由RSS修改成Flow Director,但依然保持现有默认的RSS策略。

 

【注意】以上功能会视具体时间安排调整,部分功能将极可能没法包含在1.22版本中发布,将会顺延至后续版本进行支持。

 

 

3、F-Stack实践案例

 

F-Stack自从开源后得到了全球大量研究机构、高校、公司的确定,用于进行技术研究工做或线上商业化项目,那在这里会给你们仅列举F-Stack用户实际现网业务的实践案例。

 

(一)腾讯云HttpDNS

 

HttpDNS服务主要用于移动端APP,解决其默认DNS大量存在的解析失败,解析结果跨网,解析劫持等问题,目前各大TOP APP大部分都有使用此类技术,而腾讯云DNSPod做为最先推出商用HttpDNS服务,目前服务大量用户,日请求量万亿级,历史版本介绍可参考公众号“鹅厂网事”上的文章千亿级HttpDNS服务是怎样炼成的,固然目前最新的HttpDNS 也已经迭代更新了多个版本,新的专业版支持了更多的特性功能,如IPv6,DNSPod权威数据推送,用户自定义域名解析,危险域名拦截(用户自定义是否开启及拦截哪些类别的危险域名),黑白名单,请求统计等一系列功能,也都构建在 F-Stack基础架构之上。

 

 

(二)DNSPod权威DNS

 

做为F-Stack的父项目,DNSPod权威DNS为近千万域名提供权威解析服务,受益于F-Stack的高性能网络服务,最新版本的权威DNS已经在百G机型上达到了单机1亿QPS的性能,具体见本人以前的一篇文章《基于F-Stack 的权威DNS单机1亿QPS性能优化实践》,目前DNSPod总线上容量达到了数十亿QPS,结合腾讯集团遍及全球的大带宽节点部署和先进的防御设备及算法,DNSPod在客户无感知状况下屡次成功防御TB级以上的DDoS攻击,最近一次发生在2021.8.27周五下午,多种攻击方式混合攻击,平台受攻击合计峰值超过5T。

 

 

4、其它用户态协议栈介绍

 

  • VPP

 

VPP(https://fd.io/)由思科主导,多个大厂参与,其用户态协议栈Host Stack由思科交换机协议栈发展而来,开源时间晚于F-Stack,可是是目前社区活跃度最高的用户态协议栈。

 

  • MTCP

 

MTCP(http://shader.kaist.edu/mtcp/)Stack来自韩国KAIST,在业界也有普遍的使用,主要问题是如其名字所示仅支持TCP。

 

  • Seastar

 

Seastar(https://github.com/scylladb/seastar)做为ScyllaDB的子项目,其Native stack在内网有较好的表现,内网场景使用较多。

 

  • LwIP

 

LwIP(http://savannah.nongnu.org/projects/lwip/)来自瑞典计算机科学院,轻量级协议栈,主要用于嵌入式系统等,但也有很多厂商基于LwIP进行修改移植支持本身的应用。

 

 

 

C10K