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