DPDK(Data Plane Development Kit)是數(shù)據(jù)平面開發(fā)工具包,由用于加速在各種CPU架構(gòu)上運(yùn)行的數(shù)據(jù)包處理的庫組成。
在Linux上捕獲數(shù)據(jù)包有多種方式,常見的有l(wèi)ibpcap,pf-ring等。DPDK以高性能著稱,想必相比傳統(tǒng)的數(shù)據(jù)包捕獲方式,一定有其獨(dú)到之處。
本文主要就DPDK所使用的技術(shù)點(diǎn)進(jìn)行宏觀的說明,并將其與libpcap,pf-ring進(jìn)行對比,若有寫的不對的地方請幫忙指出。
參考文檔:
[1]絕對干貨!初學(xué)者也能看懂的DPDK解析
[2]Linux 設(shè)備驅(qū)動之 UIO 機(jī)制(基本概念)
[3]PF_RING學(xué)習(xí)筆記
若出現(xiàn)侵權(quán)請聯(lián)系作者刪除。
1.DPDK 技術(shù)特點(diǎn)
傳統(tǒng)的數(shù)據(jù)包捕獲瓶頸往往在于Linux Kernel,數(shù)據(jù)流需要經(jīng)過Linux Kernel,就會帶來Kernel Spcae和User Space數(shù)據(jù)拷貝的消耗;系統(tǒng)調(diào)用的消耗;中斷處理的消耗等。
DPDK針對Linux Kernel傳統(tǒng)的數(shù)據(jù)包捕獲模式的問題,進(jìn)行了一定程度的優(yōu)化。DPDK的優(yōu)化可以概括為:
UIO+mmap 實(shí)現(xiàn)零拷貝(zero copy)
UIO+PMD 減少中斷和CPU上下文切換
HugePages 減少TLB miss
其他代碼優(yōu)化
2.UIO
2.1 UIO簡介
UIO(Userspace I/O)是運(yùn)行在用戶空間的I/O技術(shù)。Linux系統(tǒng)中一般的驅(qū)動設(shè)備都是運(yùn)行在內(nèi)核空間,而在用戶空間用應(yīng)用程序調(diào)用即可,而UIO則是將驅(qū)動的很少一部分運(yùn)行在內(nèi)核空間,而在用戶空間實(shí)現(xiàn)驅(qū)動的絕大多數(shù)功能。
圖片引自百度百科
一個設(shè)備驅(qū)動的主要任務(wù)有兩個:
存取設(shè)備的內(nèi)存
處理設(shè)備產(chǎn)生的中斷
如上圖所示,對于存取設(shè)備的內(nèi)存 ,UIO 核心實(shí)現(xiàn)了mmap();對于處理設(shè)備產(chǎn)生的中斷,內(nèi)核空間有一小部分代碼用處理中斷,用戶空間通過read()接口/dev/uioX來讀取中斷。
2.2 DPDK UIO機(jī)制
采用Linux提供UIO機(jī)制,可以旁路Kernel,將所有報(bào)文處理的工作在用戶空間完成。
圖片引自參考文檔[1]
如上圖,左邊是傳統(tǒng)的數(shù)據(jù)包獲取方式,路徑為:
網(wǎng)卡 -> Kernel驅(qū)動 -> Kernel TCP/IP協(xié)議棧 -> Socket接口 -> 業(yè)務(wù)
右邊是DPDK的方式,基于UIO。數(shù)據(jù)路徑為:
網(wǎng)卡 -> DPDK輪詢模式-> DPDK基礎(chǔ)庫 -> 業(yè)務(wù)
2.3 DPDK 零拷貝(Zero Copy)
通過UIO+mmap 實(shí)現(xiàn)數(shù)據(jù)零拷貝(zero copy)是DPDK的特點(diǎn)之一。那么常規(guī)的Linux Kernel(libpcap)以及pf-ring處理數(shù)據(jù)包的流程要進(jìn)行幾次數(shù)據(jù)拷貝呢?
libpcap
libpcap采用的是傳統(tǒng)的數(shù)據(jù)包獲取方式,如上圖左邊路徑。
網(wǎng)卡接收到數(shù)據(jù)包后,第一步需要把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。但是在這個拷貝的過程中使用了DMA(Direct Memory Access)技術(shù)。DMA 傳輸將數(shù)據(jù)從一個地址空間復(fù)制到另外一個地址空間。由CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器來實(shí)行和完成,CPU是不需要參與,也不會產(chǎn)生CPU資源消耗。因此這個第一步的拷貝可以忽略。
第二步,Kernel會將網(wǎng)卡通過DMA傳輸進(jìn)入主存(RX buffer)的內(nèi)容拷貝一份進(jìn)行處理,這里進(jìn)行了一次數(shù)據(jù)拷貝。
第三步,由于內(nèi)核空間和用戶空間的內(nèi)存是不共享的,Kernel會將數(shù)據(jù)包內(nèi)容再進(jìn)行一次拷貝用于用戶空間使用。
綜上,傳統(tǒng)的數(shù)據(jù)包捕獲方式(libpcap)會進(jìn)行兩次數(shù)據(jù)包拷貝。
pf-rfing
pf-ring采用mmap()將傳統(tǒng)的兩次拷貝減少至一次拷貝。
第一步,同樣使用DMA技術(shù),把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。
第二步,pf-ring會將網(wǎng)卡通過DMA傳輸進(jìn)入主存(RX buffer)的內(nèi)容拷貝一份放入環(huán)形緩沖區(qū)中(ring)中,這里進(jìn)行了一次數(shù)據(jù)拷貝。
第三步,使用mmap()將環(huán)形緩沖區(qū)映射至用戶空間,用戶空間可以直接訪問這個環(huán)形緩沖區(qū)中的數(shù)據(jù)。
pf-ring zc
pf-ring zc(zero copy)更是將pf-ring的一次拷貝也省去,達(dá)到了零拷貝的目的,具體的:
第一步,使用DMA技術(shù),把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。
第二步,使用mmap()直接將RX buffer的數(shù)據(jù)映射到用戶用戶空間,使用戶空間可以直接訪問RX buffer的數(shù)據(jù)。
下圖非常清晰地展示了pf-ring zc實(shí)現(xiàn)零拷貝的過程:
圖片引自參考文檔[3]
DPDK
DPDK實(shí)現(xiàn)零拷貝的方式與pf-ring zc類似,首先通過DMA將網(wǎng)卡數(shù)據(jù)拷貝至主存(RX buffer);隨后使用mmap()直接將RX buffer的數(shù)據(jù)映射到用戶用戶空間,使用戶空間可以直接訪問RX buffer的數(shù)據(jù),以此實(shí)現(xiàn)了零拷貝。
由上述可以看出,pf-ring zc和dpdk均可以實(shí)現(xiàn)數(shù)據(jù)包的零拷貝,兩者均旁路了內(nèi)核,但是實(shí)現(xiàn)原理略有不同。pf-ring zc通過zc驅(qū)動(也在應(yīng)用層)接管數(shù)據(jù)包,dpdk基于UIO實(shí)現(xiàn)。