本文列舉四個(gè)比較經(jīng)典的 Linux 收包引擎,如果還有其他你覺(jué)得ok的可以留言。這四個(gè)分別是:
libpcap
libpcap的包捕獲機(jī)制是在數(shù)據(jù)鏈路層增加一個(gè)旁路處理,不干擾系統(tǒng)自身的網(wǎng)路協(xié)議棧的處理,對(duì)發(fā)送和接收的數(shù)據(jù)包通過(guò)Linux內(nèi)核做過(guò)濾和緩沖處理,最后直接傳遞給上層應(yīng)用程序。
libpcap-mmap
libpcap-mmap是對(duì)舊的libpcap實(shí)現(xiàn)的改進(jìn),新版本的libpcap基本都采用packet_mmap機(jī)制。PACKET_MMAP通過(guò)mmap,減少一次內(nèi)存拷貝(?「第4次拷貝沒(méi)有了」?),減少了頻繁的系統(tǒng)調(diào)用,大大提高了報(bào)文捕獲的效率。
PF_RING
我們看到之前l(fā)ibpcap有4次內(nèi)存拷貝。libpcap_mmap有3次內(nèi)存拷貝。PF_RING提出的核心解決方案便是減少報(bào)文在傳輸過(guò)程中的拷貝次數(shù)。
我們可以看到,相對(duì)與libpcap_mmap來(lái)說(shuō),pfring允許用戶(hù)空間內(nèi)存直接和rx_buffer做mmap。這又減少了一次拷貝 (?「libpcap_mmap的第2次拷貝」:rx_buffer->skb)
PF-RING ZC實(shí)現(xiàn)了DNA(Direct NIC Access 直接網(wǎng)卡訪(fǎng)問(wèn))技術(shù),將用戶(hù)內(nèi)存空間映射到驅(qū)動(dòng)的內(nèi)存空間,使用戶(hù)的應(yīng)用可以直接訪(fǎng)問(wèn)網(wǎng)卡的寄存器和數(shù)據(jù)。
通過(guò)這樣的方式,避免了在內(nèi)核對(duì)數(shù)據(jù)包緩存,減少了一次拷貝(?「libpcap的第1次拷貝」?,DMA到內(nèi)核緩沖區(qū)的拷貝)。這就是完全的零拷貝。
其缺點(diǎn)是,只有一個(gè) 應(yīng)用可以在某個(gè)時(shí)間打開(kāi)DMA ring(請(qǐng)注意,現(xiàn)在的網(wǎng)卡可以具有多個(gè)RX / TX隊(duì)列,從而就可以在每個(gè)隊(duì)列上同時(shí)一個(gè)應(yīng)用程序),換而言之,用戶(hù)態(tài)的多個(gè)應(yīng)用需要彼此溝通才能分發(fā)數(shù)據(jù)包。
DPDK
pf-ring zc和dpdk均可以實(shí)現(xiàn)數(shù)據(jù)包的零拷貝,兩者均旁路了內(nèi)核,但是實(shí)現(xiàn)原理略有不同。pf-ring zc通過(guò)zc驅(qū)動(dòng)(也在應(yīng)用層)接管數(shù)據(jù)包,dpdk基于UIO實(shí)現(xiàn)。
1 UIO+mmap 實(shí)現(xiàn)零拷貝(zero copy)
UIO(Userspace I/O)是運(yùn)行在用戶(hù)空間的I/O技術(shù)。Linux系統(tǒng)中一般的驅(qū)動(dòng)設(shè)備都是運(yùn)行在內(nèi)核空間,而在用戶(hù)空間用應(yīng)用程序調(diào)用即可,而UIO則是將驅(qū)動(dòng)的很少一部分運(yùn)行在內(nèi)核空間,而在用戶(hù)空間實(shí)現(xiàn)驅(qū)動(dòng)的絕大多數(shù)功能。采用Linux提供UIO機(jī)制,可以旁路Kernel,將所有報(bào)文處理的工作在用戶(hù)空間完成。
2 UIO+PMD 減少中斷和CPU上下文切換
DPDK的UIO驅(qū)動(dòng)屏蔽了硬件發(fā)出中斷,然后在用戶(hù)態(tài)采用主動(dòng)輪詢(xún)的方式,這種模式被稱(chēng)為PMD(Poll Mode Driver)。
與DPDK相比,pf-ring(no zc)使用的是NAPI polling和應(yīng)用層polling,而pf-ring zc與DPDK類(lèi)似,僅使用應(yīng)用層polling。
3 HugePages 減少TLB miss
在操作系統(tǒng)引入MMU(Memory Management Unit)后,CPU讀取內(nèi)存的數(shù)據(jù)需要兩次訪(fǎng)問(wèn)內(nèi)存。第一次要查詢(xún)頁(yè)表將邏輯地址轉(zhuǎn)換為物理地址,然后訪(fǎng)問(wèn)該物理地址讀取數(shù)據(jù)或指令。
為了減少頁(yè)數(shù)過(guò)多,頁(yè)表過(guò)大而導(dǎo)致的查詢(xún)時(shí)間過(guò)長(zhǎng)的問(wèn)題,便引入了TLB(Translation Lookaside Buffer),可翻譯為地址轉(zhuǎn)換緩沖器。TLB是一個(gè)內(nèi)存管理單元,一般存儲(chǔ)在寄存器中,里面存儲(chǔ)了當(dāng)前最可能被訪(fǎng)問(wèn)到的一小部分頁(yè)表項(xiàng)。
引入TLB后,CPU會(huì)首先去TLB中尋址,由于TLB存放在寄存器中,且其只包含一小部分頁(yè)表項(xiàng),因此查詢(xún)速度非常快。若TLB中尋址成功(TLB hit),則無(wú)需再去RAM中查詢(xún)頁(yè)表;若TLB中尋址失?。═LB miss),則需要去RAM中查詢(xún)頁(yè)表,查詢(xún)到后,會(huì)將該頁(yè)更新至TLB中。
而DPDK采用HugePages ,在x86-64下支持2MB、1GB的頁(yè)大小,大大降低了總頁(yè)個(gè)數(shù)和頁(yè)表的大小,從而大大降低TLB miss的幾率,提升CPU尋址性能。
4 其它優(yōu)化
XDP
xdp代表eXpress數(shù)據(jù)路徑,使用ebpf 做包過(guò)濾,相對(duì)于dpdk將數(shù)據(jù)包直接送到用戶(hù)態(tài),用用戶(hù)態(tài)當(dāng)做快速數(shù)據(jù)處理平面,xdp是在驅(qū)動(dòng)層創(chuàng)建了一個(gè)數(shù)據(jù)快速平面。在數(shù)據(jù)被網(wǎng)卡硬件dma到內(nèi)存,分配skb之前,對(duì)數(shù)據(jù)包進(jìn)行處理。
請(qǐng)注意,XDP并沒(méi)有對(duì)數(shù)據(jù)包做Kernel bypass,它只是提前做了一點(diǎn)預(yù)檢而已。
相對(duì)于DPDK,XDP具有以下優(yōu)點(diǎn):
XDP的使用場(chǎng)景包括:
OK,以上就是今天的分享,如果你覺(jué)得還有其他的收包引擎,可以留言分享。
以上就是Linux經(jīng)典的幾款收包引擎的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注www.92cms.cn其它相關(guān)文章!