聊一聊Linux網(wǎng)絡(luò)性能王者——XDP技術(shù)
大家好,今天我們通過(guò)幾張圖來(lái)聊一聊XDP技術(shù)。
XDP技術(shù)對(duì)于很多Linux開(kāi)發(fā)人員來(lái)說(shuō)是一個(gè)很陌生的技術(shù),如果你是一個(gè)Linux開(kāi)發(fā)人員,恰好你從事的網(wǎng)絡(luò)相關(guān)的開(kāi)發(fā)工作,如果你不懂XDP技術(shù),這是一個(gè)非常大的損失。
這個(gè)是我一個(gè)真實(shí)的經(jīng)歷,曾經(jīng)我采用XDP技術(shù)優(yōu)化過(guò)一個(gè)項(xiàng)目,讓一個(gè)項(xiàng)目的網(wǎng)絡(luò)處理性能提高了3-4倍,可能很多小伙伴會(huì)懷疑項(xiàng)目原本性能就很差,所以才會(huì)有很大的提升空間。
我想說(shuō)的是,按照原來(lái)的軟件架構(gòu),不管你怎么優(yōu)化,性能的瓶頸是不可能突破的,唯一的方式是采用更高效的架構(gòu),從更高維度去解決問(wèn)題。
后續(xù)我的項(xiàng)目魔法盒子也會(huì)用上XDP技術(shù),采用XDP技術(shù)后,魔法盒子的網(wǎng)絡(luò)性能估計(jì)能夠提高3倍左右。
1.XDP技術(shù)簡(jiǎn)介
1.1 XDP技術(shù)背景
隨著超高帶寬網(wǎng)絡(luò)技術(shù)10G,40G,100G網(wǎng)絡(luò)的出現(xiàn),Linux內(nèi)核協(xié)議棧越來(lái)越不能適應(yīng)新的網(wǎng)絡(luò)技術(shù)的發(fā)展,Linux內(nèi)核協(xié)議棧似乎成為了網(wǎng)絡(luò)性能的瓶頸和雞肋,為了解決這個(gè)尷尬的處境,Linux內(nèi)核引入了一個(gè)新的技術(shù)內(nèi)核旁路(Kernel Bypass)技術(shù),內(nèi)核旁路技術(shù)的核心思想是網(wǎng)絡(luò)數(shù)據(jù)包跳過(guò)內(nèi)核協(xié)議棧,直接由用戶程序處理,這樣可以避免內(nèi)核協(xié)議棧的開(kāi)銷,大大提高網(wǎng)絡(luò)性能。
XDP就是屬于Linux自己的內(nèi)核旁路技術(shù),與之對(duì)應(yīng)的還有一種內(nèi)核旁路技術(shù)DPDK技術(shù),DPDK擁有非常不錯(cuò)的性能,但是DPDK技術(shù)并不非常適用于Linux系統(tǒng)。
1.2 XDP是什么?
XDP是一種Linux內(nèi)核技術(shù),通過(guò)使用eBPF機(jī)制,在內(nèi)核空間中實(shí)現(xiàn)高性能的數(shù)據(jù)包處理和轉(zhuǎn)發(fā)。
它可以顯著提高網(wǎng)絡(luò)性能,并提供了靈活的編程接口,使用戶能夠?qū)崿F(xiàn)各種自定義的網(wǎng)絡(luò)功能,與傳統(tǒng)的用戶空間數(shù)據(jù)包處理相比,XDP可以顯著降低數(shù)據(jù)包處理的延遲和CPU占用。
XDP技術(shù)工作模式:
原生模式(性能高,需要網(wǎng)卡支持)驅(qū)動(dòng)模式,將XDP程序運(yùn)行在網(wǎng)卡驅(qū)動(dòng)中,從網(wǎng)卡驅(qū)動(dòng)中將網(wǎng)絡(luò)數(shù)據(jù)包重定向,該模式支持的網(wǎng)卡較多且性能也很高,如果網(wǎng)卡支持的話,盡量使用該模式。
卸載模式(性能最高,支持的網(wǎng)卡最少)將XDP程序直接卸載到網(wǎng)卡,該模式支持的網(wǎng)卡少,暫不做討論。
通用模式(性能良好,Linux內(nèi)核支持最好)XDP程序運(yùn)行在Linux內(nèi)核協(xié)議棧入口,無(wú)需驅(qū)動(dòng)支持,性能低于XDP其他的兩種模式,但是即使XDP通用模式,也會(huì)給你的系統(tǒng)性能帶來(lái)一定的提升。
后續(xù)會(huì)有專門(mén)的專題來(lái)講XDP技術(shù),這里不展開(kāi)討論。
2.AF_XDP工作原理
2.1 整體架構(gòu)
很多同學(xué)容易將XDP和AF_XDP技術(shù)給弄混淆。
- XDP技術(shù)是基于BPF技術(shù)的一種新的網(wǎng)絡(luò)技術(shù)。
- AF_XDP是XDP技術(shù)的一種應(yīng)用場(chǎng)景,AF_XDP是一種高性能Linux socket。
AF_XDP需要通過(guò)socket函數(shù)創(chuàng)建。
socket(AF_XDP, SOCK_RAW, 0);
AF_XDP技術(shù)會(huì)涉及到一些比較重要的知識(shí)點(diǎn):
圖片
- AF_XDP想要XDP程序配合,才能完成網(wǎng)絡(luò)數(shù)據(jù)包收發(fā)。
- XDP程序主要工作是根據(jù)以太網(wǎng)幀的相關(guān)信息如:MAC地址,五元組信息等,進(jìn)行數(shù)據(jù)包的過(guò)濾和重定向。
- AF_XDP處理的是以太網(wǎng)數(shù)據(jù)幀,所以用戶程序發(fā)送和接收的是以太網(wǎng)數(shù)據(jù)幀。
- 用戶程序,AF_XDP,XDP會(huì)操作一個(gè)共享的內(nèi)存區(qū)域,稱之為UMEM。
- 網(wǎng)絡(luò)數(shù)據(jù)包的接收和發(fā)送需要用到4個(gè)無(wú)鎖環(huán)形隊(duì)列。
2.2 UMEM共享內(nèi)存
UMEM共享內(nèi)存通過(guò)setsockopt函數(shù)進(jìn)行申請(qǐng)。
setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr));
UMEM共享內(nèi)存通常以4K為一個(gè)單元,每個(gè)單元可以存儲(chǔ)一個(gè)數(shù)據(jù)包,UMEM共享內(nèi)存通常為4096個(gè)單元。
接收和發(fā)送的數(shù)據(jù)包都是存儲(chǔ)在UMEM內(nèi)存單元。
用戶程序和內(nèi)核都可以直接操作這塊內(nèi)存區(qū)域,所以發(fā)送和接收數(shù)據(jù)包時(shí),只是簡(jiǎn)單的內(nèi)存拷貝,不需要進(jìn)行系統(tǒng)調(diào)用。
用戶程序需要維護(hù)一個(gè)UMEM內(nèi)存使用記錄,記錄每一個(gè)UMEM單元是否已被使用,每個(gè)記錄都會(huì)有一個(gè)相對(duì)地址,用于定位UMEM內(nèi)存單元地址。
2.2 無(wú)鎖環(huán)形隊(duì)列
AF_XDP socket總共有4個(gè)無(wú)鎖環(huán)形隊(duì)列,分別為:
- 填充隊(duì)列(FILL RING)
- 已完成隊(duì)列(COMPLETION RING)
- 發(fā)送隊(duì)列(TX RING)
- 接收隊(duì)列(RX RING)
圖片
環(huán)形隊(duì)列創(chuàng)建方式:
//創(chuàng)建FILL RINGsetsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING,&umem->config.fill_size, sizeof(umem->config.fill_size)); //創(chuàng)建COMPLETION RINGsetsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING,&umem->config.comp_size, sizeof(umem->config.comp_size));//創(chuàng)建RX RING setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,&xsk->config.rx_size, sizeof(xsk->config.rx_size));//創(chuàng)建TX RING setsockopt(xsk->fd, SOL_XDP, XDP_TX_RING, &xsk->config.tx_size, sizeof(xsk->config.tx_size));
4個(gè)環(huán)形隊(duì)列實(shí)現(xiàn)方式基本相同,環(huán)形隊(duì)列是對(duì)數(shù)組進(jìn)行封裝的數(shù)據(jù)結(jié)構(gòu),環(huán)形隊(duì)列由5個(gè)重要部分組成:
- 生產(chǎn)者序號(hào)(producer)
生產(chǎn)者序號(hào)用于指示數(shù)組當(dāng)前可生產(chǎn)的元素位置,如果隊(duì)列已滿,將不能再生產(chǎn)。
- 消費(fèi)者序號(hào)(consumer)
消費(fèi)者序號(hào)用于指示當(dāng)前可消費(fèi)的元素位置,如果隊(duì)列已空,將不能再消費(fèi)。
- 隊(duì)列長(zhǎng)度(len)
隊(duì)列長(zhǎng)度即數(shù)組長(zhǎng)度。
- 隊(duì)列掩碼(mask)
mask=len-1,生產(chǎn)者和消費(fèi)者序號(hào)不能直接使用,需要配合掩碼使用,producer,consumer和mask進(jìn)行與運(yùn)算,可以獲取到數(shù)組的索引值。
- 固定長(zhǎng)度數(shù)組
數(shù)組的每一個(gè)元素記錄了UMEM單元的相對(duì)地址,如果UMEM單元有發(fā)送和接收的數(shù)據(jù)包,還會(huì)記錄數(shù)據(jù)包的長(zhǎng)度。
環(huán)形隊(duì)列的無(wú)鎖化通過(guò)原子變量來(lái)實(shí)現(xiàn),原子變量和原子操作在高性能編程中經(jīng)常會(huì)用到。
2.3 AF_XDP接收數(shù)據(jù)包
AF_XDP接收數(shù)據(jù)包需要FILL RING,RX RING兩個(gè)環(huán)形隊(duì)列配合工作。
第一步:XDP程序獲取可用UMEM單元。
FILL RING記錄了可以用來(lái)接收數(shù)據(jù)包的UMEM單元數(shù)量,用戶程序根據(jù)UMEM使用記錄,定期的往FILL RING生產(chǎn)可用UMEM單元。
第二步:XDP填充新的接收數(shù)據(jù)包
XDP程序消費(fèi)FILL RING中UMEM單元用于存放網(wǎng)絡(luò)數(shù)據(jù)包,接收完數(shù)據(jù)包后,將UMEM單元和數(shù)據(jù)包長(zhǎng)度重新打包,填充至RX RING隊(duì)列,生產(chǎn)一個(gè)待接收的數(shù)據(jù)包。
第三步:用戶程序接收網(wǎng)絡(luò)數(shù)據(jù)包
用戶程序檢測(cè)到RX RING有待接的收數(shù)據(jù)包,消費(fèi)RX RING中數(shù)據(jù)包,將數(shù)據(jù)包信息從UMEM單元中拷貝至用戶程序緩沖區(qū),同時(shí)用戶程序需要再次填充FILL RING隊(duì)列推動(dòng)XDP繼續(xù)接收數(shù)據(jù)。
圖片
2.4 AF_XDP發(fā)送數(shù)據(jù)包
AF_XDP發(fā)送數(shù)據(jù)包需要COMP RING,TX RING兩個(gè)環(huán)形隊(duì)列配合工作。
第一步:用戶程序確保有足夠的UMEM發(fā)送單元
COMP RING記錄了已完成發(fā)送的數(shù)據(jù)包(UMEM單元)數(shù)量,用戶程序需要回收這部分UMEM單元,確保有足夠的UMEM發(fā)送單元。
第二步:用戶程序發(fā)送數(shù)據(jù)包
用戶程序申請(qǐng)一個(gè)可用的UMEM單元,將數(shù)據(jù)包拷貝至該UMEM單元,然后生產(chǎn)一個(gè)待發(fā)送數(shù)據(jù)包填充值TX RING。
第三步:XDP發(fā)送數(shù)據(jù)包
XDP程序檢測(cè)到TX RING中有待發(fā)送數(shù)據(jù)包,從TX RING消費(fèi)一個(gè)數(shù)據(jù)包進(jìn)行發(fā)送,發(fā)送完成后,將UMEM單元填充至COMP RING,生產(chǎn)一個(gè)已完成發(fā)送數(shù)據(jù)包,用戶程序?qū)?duì)該數(shù)據(jù)包UMEM單元進(jìn)行回收。
圖片
3. AF_XDP高效的秘密
AF_XDP之所以高效,主要有三大原因:
- 內(nèi)核旁路技術(shù)
內(nèi)核旁路技術(shù)在處理網(wǎng)絡(luò)數(shù)據(jù)包的時(shí)候,可以跳過(guò)Linux內(nèi)核協(xié)議棧,相當(dāng)于走了捷徑,這樣可以降低鏈路開(kāi)銷。
- 內(nèi)存映射
用戶程序和內(nèi)核共享UMEM內(nèi)存和無(wú)鎖環(huán)形隊(duì)列,采用mmap技術(shù)將內(nèi)存進(jìn)行映射,用戶操作UMEM內(nèi)存不需要進(jìn)行系統(tǒng)調(diào)用,減少了系統(tǒng)調(diào)用上下文切換成本。
- 無(wú)鎖環(huán)形隊(duì)列
無(wú)鎖環(huán)形隊(duì)列采用原子變量實(shí)現(xiàn),可以減少線程切換和上下文切換成本。
基于以上幾點(diǎn),AF_XDP必然是一個(gè)高性能的網(wǎng)絡(luò)技術(shù),由于目前沒(méi)有一個(gè)能夠測(cè)試XDP極限性能的測(cè)試環(huán)境,大家如果對(duì)AF_XDP技術(shù)感興趣,可以自行上網(wǎng)搜索相關(guān)資料。