C10K C10M 通過DPDK+用戶態協議棧來進行內核旁路來提升網絡性能


千萬並發連接下,如何保障網絡性能? https://mp.weixin.qq.com/s/lDhCoLN0mknquJcO15Fd2Q

千萬並發連接下,如何保障網絡性能?

圖片

 

圖片

 

過去幾十年互聯網呈爆發式的增長,內容的豐富以及層出不窮的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開源版本歷史

 

  • 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

     

     

二、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版本中發布,將會順延至后續版本進行支持。

 

 

三、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(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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM