3月份寫過一篇《DPDK的基本原理》髓棋。DPDK 是好同志,針對(duì)網(wǎng)絡(luò)轉(zhuǎn)發(fā)提供了很好的純軟理念和解決實(shí)現(xiàn)方案膳犹,只是有點(diǎn)高冷儒喊。DPDK 本身并不包含 TCP/IP 協(xié)議棧币呵。這給大部分網(wǎng)絡(luò)程序開發(fā)者設(shè)置了不小的門檻余赢。
于是芯义,出現(xiàn)了一些基于 DPDK 的用戶態(tài)協(xié)議棧妻柒,降低開發(fā)者的難度:
mTCP
mTCP 是一個(gè)針對(duì)多核系統(tǒng)的高可擴(kuò)展性的用戶空間 TCP/IP 協(xié)議棧。IwIP
IwIP 是一個(gè)針對(duì) RAM 平臺(tái)的精簡(jiǎn)版的 TCP/IP 協(xié)議棧實(shí)現(xiàn)绑警。Seastar
Seastar 是一個(gè)開源的央渣,基于 C++ 的支持高并發(fā)和低延遲的異步編程高性能庫(kù)。F-Stack
F-Stack 是一個(gè)用戶態(tài)的高性能的網(wǎng)絡(luò)接入開發(fā)包北启,基于DPDK拔第、FreeBSD協(xié)議棧蚊俺、微線程接口等實(shí)現(xiàn)的高性能網(wǎng)絡(luò)服務(wù)器。
再回顧一下 DPDK
一批钠、基于 OS 內(nèi)核的轉(zhuǎn)發(fā)技術(shù)有哪些問題暂殖?
局部性失效:
網(wǎng)絡(luò)處理服務(wù)往往運(yùn)行在多核環(huán)境中。一個(gè)數(shù)據(jù)包的生命周期可能會(huì)運(yùn)轉(zhuǎn)在多個(gè)核上(或vCPU)踩窖,比如驅(qū)動(dòng)中斷處理在 Core0晨横,內(nèi)核態(tài)處理在 Core1,用戶態(tài)處理在 Core2啥供,這樣跨越多個(gè)核心伙狐,CPU緩存可能會(huì)失效。加上跨 NUMA 的影響罢防,這個(gè)問題可能更加嚴(yán)重唉侄。中斷導(dǎo)致的開銷和鎖:
網(wǎng)口收到網(wǎng)絡(luò)報(bào)文,產(chǎn)生硬件中斷恬叹,級(jí)別很高同眯,可以打斷相對(duì)優(yōu)先級(jí)較低的軟中斷和其他系統(tǒng)調(diào)用嗽测。這些硬件中斷會(huì)導(dǎo)致系統(tǒng)上下文頻繁切換。同時(shí)疏魏,任務(wù)切換往往對(duì)應(yīng)同步和加鎖晤愧。這些都會(huì)帶來嚴(yán)重消耗,特別是大量短連接只厘,會(huì)導(dǎo)致系統(tǒng)性能劇烈下降舅巷。內(nèi)存多次拷貝導(dǎo)致的開銷:
基于 OS 內(nèi)核的轉(zhuǎn)發(fā),數(shù)據(jù)包的路徑是:網(wǎng)口 -> DMA -> 內(nèi)核緩沖區(qū)(內(nèi)核態(tài)驅(qū)動(dòng))-> 用戶態(tài)空間赋元。其中從“內(nèi)核緩沖區(qū)”到“用戶態(tài)空間”的拷貝占據(jù)整個(gè)數(shù)據(jù)包處理流程幾乎一半的時(shí)間搁凸。這里正是性能下降的重要原因之一。
二褥芒、DPDK技術(shù)帶來的改變:
- 用戶態(tài)驅(qū)動(dòng)嫡良,繞過內(nèi)核驅(qū)動(dòng)收包,減少內(nèi)存拷貝少辣。
DPDK 能夠繞過內(nèi)核協(xié)議棧羡蛾,本質(zhì)上是得益于 UIO 技術(shù)痴怨,通過 UIO 能夠攔截中斷器予,并重設(shè)中斷回調(diào)行為,從而繞過內(nèi)核協(xié)議棧后續(xù)的處理流程爱葵。
UIO 設(shè)備的實(shí)現(xiàn)機(jī)制其實(shí)是對(duì)用戶空間暴露文件接口反浓,比如當(dāng)注冊(cè)一個(gè) UIO 設(shè)備 uioX雷则,就會(huì)出現(xiàn)文件 /dev/uioX,對(duì)該文件的讀寫就是對(duì)設(shè)備內(nèi)存的讀寫度迂。
- 支持 CPU 親和性綁定惭墓,支持對(duì)多核多線程的支撐而姐,每個(gè)核對(duì)應(yīng)一個(gè)免鎖隊(duì)列,減少線程調(diào)度和鎖的消耗吭狡。
DPDK 的多核處理
摘自我的上一篇簡(jiǎn)書 http://www.reibang.com/p/4b3d42fc5733
對(duì) NUMA 的優(yōu)化划煮,盡量在處理時(shí)不跨 NUMA。
利用 HugePage 技術(shù)器躏,減少 CacheMiss 的情況蟹略。
三、騰訊 F-Stack
如開篇所說揽浙,DPDK 不支持 TCP/IP 協(xié)議棧意敛,相對(duì)基于 Linux 內(nèi)核編程草姻,給開發(fā)者帶來不小的麻煩,門檻變高敞曹,因此基于 DPDK 技術(shù)综膀,出現(xiàn)了一些用戶態(tài)協(xié)議棧。騰訊開源的 F-Stack 可能是一個(gè)不錯(cuò)的選型纲刀。
F-Stack 好比膠水担平,粘合了 DPDK 和 FreeBSD TCP/IP 協(xié)議棧暂论,純 C 語(yǔ)言編寫,API 基本兼容 Socket/Epoll/Kqueue展哭,這樣更有利于原有系統(tǒng)的移植。
FreeBSD 有很多成熟的網(wǎng)絡(luò)工具您市,F(xiàn)-Stack 的重點(diǎn)正是基于 DPDK 來移植這些網(wǎng)絡(luò)工具役衡,降低使用人員的門檻。比如:
- ifconfig:網(wǎng)絡(luò)管理
- netstat:網(wǎng)絡(luò)管理
- sysctl:網(wǎng)絡(luò)管理
- netgraph:通過 hook 機(jī)制榕莺,類似 Linux 下的 netfilter钉鸯,關(guān)于 netfilter邮辽,可以參見 海邊頑石的專欄
- IPfw:防火墻,類似 Linux 下的 IPtabes
F-Stack 整體架構(gòu)可以從三個(gè)部分來看(參考騰訊 F-Stack 團(tuán)隊(duì)的官方文章 《全用戶態(tài)網(wǎng)絡(luò)開發(fā)套件 F-Stack 架構(gòu)分析》):
-
基于 DPDK 的網(wǎng)絡(luò)報(bào)文處理能力
主要的能力和概念仍來自 DPDK及塘,比如內(nèi)存免拷貝、CPU核和網(wǎng)卡隊(duì)列的綁定芳肌、免鎖隊(duì)列亿笤、NUMA友好等。
- 各線程綁定獨(dú)立的 CPU 內(nèi)核和網(wǎng)卡隊(duì)列(設(shè)置網(wǎng)卡 RSS 以散列報(bào)文)汪榔,每個(gè) NUMA 節(jié)點(diǎn)使用獨(dú)立的內(nèi)存池肃拜。
- 使用 DPDK 輪詢模式取代網(wǎng)卡驅(qū)動(dòng)內(nèi)核中斷模式燃领。
- 使用 DPDK 用戶態(tài)驅(qū)動(dòng)直接對(duì)接網(wǎng)卡收包(UIO技術(shù)),減少內(nèi)核態(tài)拷貝剥悟。
- 設(shè)置 DPDK RSS Hash 保證報(bào)文負(fù)載均衡(IP+Port)。
- 各線程擁有獨(dú)立的表資源略板,通過免鎖機(jī)制消除協(xié)議處理過程資源競(jìng)爭(zhēng)慈缔。
-
基于 FreeBSD 的上層協(xié)議棧能力
主要將 FreeBSD 移植到用戶態(tài)胀糜,但改動(dòng)不大,這樣后面對(duì) FreeBSD 的更新同步會(huì)更容易距帅。騰訊 F-Stack 團(tuán)隊(duì)針對(duì) FreeBSD 做了一些優(yōu)化(參考騰訊 F-Stack 團(tuán)隊(duì)的官方文章 《全用戶態(tài)網(wǎng)絡(luò)開發(fā)套件 F-Stack 架構(gòu)分析》)
- 內(nèi)存分配優(yōu)化碌秸。
- 定時(shí)器優(yōu)化悄窃。
- 徹底移除內(nèi)核線程、中斷線程等恩敌,統(tǒng)一進(jìn)行輪詢處理横媚。
- 移除文件系統(tǒng)相關(guān)的綁定灯蝴。
- 移除FreeBSD內(nèi)核中的所有鎖。
-
良好的 API 兼容性能力
提供了類 POSIX 接口和微線程框架耕肩,方便現(xiàn)有應(yīng)用接入问潭,替換接口睦授。微線程框架,移植自騰訊開源的毫秒服務(wù)MSEC里使用的spp_rpc怖辆。具有同步編程、異步執(zhí)行的特點(diǎn)淑廊,無需處理復(fù)雜的異步邏輯。
F-Stack 的問題及優(yōu)化:
由于使用 DPDK 輪詢模式特咆,CPU 使用率會(huì)一直是100%季惩, F-Stack 會(huì)引入 DPDK 輪詢 + 中斷模式,當(dāng)連續(xù)幾次輪詢沒有收到包后腻格,轉(zhuǎn)為中斷模式画拾,有包后再進(jìn)行輪詢,直到又沒包進(jìn)來菜职,循環(huán)往復(fù)青抛。
由于DPDK接管了網(wǎng)卡,所有的數(shù)據(jù)包都將在用戶態(tài)運(yùn)行酬核,導(dǎo)致常規(guī)的網(wǎng)絡(luò)工具(如 tcpdump蜜另、ifconfig嫡意、netstat)都無法使用举瑰,于是 F-Stack 對(duì)一些工具進(jìn)行了移植。抓包可以在 config.ini 里配置開啟蔬螟,抓包文件可以在 wireshark 里直接進(jìn)行分析此迅。
一些優(yōu)秀實(shí)踐
使用性能高的多核 CPU,在 config.ini 里配置 lcore_mask 來進(jìn)行核綁定旧巾,減少多核調(diào)度帶來的效率下降邮屁。
使用 10G、25G菠齿、40G 多隊(duì)列網(wǎng)卡,支持硬件卸載坐昙,支持 RSS 隊(duì)列數(shù)越多越好绳匀。越容易散列開,越容易并行起來炸客。
配置盡可能多的 HugePage疾棵。
沒事不要抓包,在 config.ini 關(guān)閉抓包痹仙。