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

點擊一鍵訂閱《雲薦大咖》專欄,獲取官方推薦精品內容,學技術不迷路!

 

 過去幾十年互聯網呈爆發式的增長,對網絡性能和基礎設施提出挑戰,用戶對於高性能的網絡處理和用戶態協議棧均有需求,因此騰訊雲通過DPDK+用戶態協議棧打造了獨立的通用網絡架構F-Stack來提升網絡性能。文章將會詳細介紹F-stack的設計理念及應用方式。

 

 

過去幾十年互聯網呈爆發式的增長,內容的豐富以及層出不窮的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 背景故事進行了解。

 

1. 協議棧功能完善,且有大量工具可以對網絡進行調試分析,如sysctl、ifconfig、netstat、netgraph、ipfw、ndp等。

2. 可以跟進社區的改進,無需自己開發維護,有原始用戶態移植可供參考,大幅減少工作量,見libplebnetlibuinet

3. 相比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 Release 1.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 由思科主導,多個大廠參與,其用戶態協議棧 Host Stack 由思科交換機協議棧發展而來,開源時間晚於 F-Stack,但是是目前社區活躍度最高的用戶態協議棧。

MTCP

MTCP Stack 來自韓國 KAIST,在業界也有廣泛的使用,主要問題是如其名字所示僅支持 TCP。

Seastar

Seastar作爲ScyllaDB的子項目,其 Native stack 在內網有較好的表現,內網場景使用較多。

LwIP

LwIP 來自瑞典計算機科學院,輕量級協議棧,主要用於嵌入式系統等,但也有不少廠商基於 LwIP 進行修改移植支持自己的應用。

 

 

 

 《雲薦大咖》是騰訊雲加社區精品內容專欄。雲薦官特邀行業佼者,聚焦於前沿技術的落地及理論實踐之上,持續爲您解讀雲時代熱點技術、探索行業發展新機點擊一鍵訂閱,我們將爲你定期推送精品內容。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章