共计 5736 个字符,预计需要花费 15 分钟才能阅读完成。
过来几十年互联网呈爆发式的增长,内容的丰盛以及层出不穷的 DDoS 攻打等,对网络性能提出了极大的挑战,也同样促成了网络基础设施的疾速倒退。运营商的带宽越来越大,CPU/ 网卡等硬件的性能也会越来越强。但在很长时间内,软件的性能晋升落后于硬件的性能晋升,并重大限度了应用程序的性能,大部分工夫不得不依附堆机器来应答,造成了大量的资源节约和老本进步。
随着软件的一直倒退,在新世纪的第一个 10 年时,通过多线程和事件驱动(kqueue/epoll 等)解决了 C10K 的问题。然而在第二个 10 年却不堪重负,亟需新的解决方案来应答网络流量的增长。
比方腾讯云对外提供的 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。
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 也始终在继续保护中,预计 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 版本中公布,将会顺延至后续版本进行反对。
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。
其余用户态协定栈介绍
VPP
VPP 由思科主导,多个大厂参加,其用户态协定栈 Host Stack 由思科交换机协定栈倒退而来,开源工夫晚于 F-Stack,然而是目前社区活跃度最高的用户态协定栈。
MTCP
MTCP Stack 来自韩国 KAIST,在业界也有宽泛的应用,次要问题是如其名字所示仅反对 TCP。
Seastar
Seastar 作为 ScyllaDB 的子项目,其 Native stack 在内网有较好的体现,内网场景应用较多。
LwIP
LwIP 来自瑞典计算机科学院,轻量级协定栈,次要用于嵌入式零碎等,但也有不少厂商基于 LwIP 进行批改移植反对本人的利用。