DPDK 网络加速在 NFV 中的应用
目錄
文章目錄
目錄前文列表傳統(tǒng)內(nèi)核協(xié)議棧的數(shù)據(jù)轉(zhuǎn)發(fā)性能瓶頸是什么?DPDKDPDK 基本技術(shù)DPDK 架構(gòu)DPDK 核心組件應用 NUMA 親和性技術(shù)減少跨 NUMA 內(nèi)存訪問應用 CPU 綁核技術(shù)減少上下文切換損耗應用大頁內(nèi)存技術(shù)減少 TLB miss應用 PMD 輪詢技術(shù)減少網(wǎng)卡外設的硬件中斷應用 UIO 和內(nèi)存池技術(shù)減少內(nèi)存拷貝應用無鎖循環(huán)隊列較少鎖操作對 CPU 的開銷DPDK 優(yōu)化技術(shù)DPDK 性能影響因素硬件結(jié)構(gòu)的影響OS 版本及其內(nèi)核的影響OVS 性能問題內(nèi)存管理CPU 核間無鎖通信設置正確的目標 CPU 類型與模式優(yōu)化方案DPDK 在 NFV 中的應用參考文章
前文列表
《OpenStack Nova 高性能虛擬機之 NUMA 架構(gòu)親和》
《OpenStack Nova 高性能虛擬機之 CPU 綁定》
《OpenStack Nova 高性能虛擬機之大頁內(nèi)存》
《多進程、多線程與多處理器計算平臺的性能問題》
《計算機組成原理 — 存儲系統(tǒng)》
《計算機組成原理 — 輸入輸出系統(tǒng)》
《計算機組成原理 — 總線系統(tǒng)》
《Linux 的零拷貝技術(shù)》
《數(shù)據(jù)包從物理網(wǎng)卡流經(jīng) Open vSwitch 進入 OpenStack 云主機的流程》
傳統(tǒng)內(nèi)核協(xié)議棧的數(shù)據(jù)轉(zhuǎn)發(fā)性能瓶頸是什么?
在 x86 結(jié)構(gòu)中,處理數(shù)據(jù)包的傳統(tǒng)方式是 CPU 中斷方式,即網(wǎng)卡驅(qū)動接收到數(shù)據(jù)包后通過中斷通知 CPU 處理,然后由 CPU 拷貝數(shù)據(jù)并交給內(nèi)核協(xié)議棧。在數(shù)據(jù)量大時,這種方式會產(chǎn)生大量 CPU 中斷,導致 CPU 無法運行其他程序。
傳統(tǒng)內(nèi)核協(xié)議棧的數(shù)據(jù)轉(zhuǎn)發(fā)流程:
傳統(tǒng)內(nèi)核協(xié)議棧的數(shù)據(jù)轉(zhuǎn)發(fā)性能瓶頸有:
硬件中斷導致的線程/進程切換:硬件中斷請求會搶占優(yōu)先級較低的軟件中斷,頻繁到達的硬件中斷和軟中斷意味著頻繁的線程切換,隨著而來的就是運行模式切換、上下文切換、線程調(diào)度器負載、高速緩存缺失(Cache Missing)、多核緩存共享數(shù)據(jù)同步、競爭鎖等一系列的 CPU 性能損耗。
內(nèi)存拷貝:網(wǎng)卡驅(qū)動位于內(nèi)核態(tài),網(wǎng)絡驅(qū)動接收到的數(shù)據(jù)包后會經(jīng)過內(nèi)核協(xié)議棧的處理,然后再拷貝到處于用戶態(tài)的應用層緩沖區(qū),這樣的數(shù)據(jù)拷貝是很耗時間的。據(jù)統(tǒng)計,這個拷貝的時間會占數(shù)據(jù)包處理流程時間的 57.1%。
多處理器平臺的 CPU 漂移:一個數(shù)據(jù)包可能中斷在 CPU0,內(nèi)核態(tài)處理在 CPU1,用戶態(tài)處理在 CPU2,這樣跨多個物理核(Core)的處理,導致了大量的 CPU Cache Miss,造成局部性失效。如果是 NUMA 架構(gòu),還會出現(xiàn)跨 NUMA remote access Memory 的情況,這些都極大地影響了 CPU 性能。
緩存失效:傳統(tǒng)服務器大多采用頁式虛擬存儲器,內(nèi)存頁默認為 4K 的小頁,所以在存儲空間較大的處理機上會存在大量的頁面映射條目。同時因為 TLB 緩存空間有限,最終導致了 TLB 快表的映射條目頻繁變更,產(chǎn)生大量的快頁表 Cache Miss。
與之對應的優(yōu)化方案為:
使用 NUMA 親和:避免 CPU 跨 NUMA 訪問內(nèi)存。
使用 CPU 綁核:避免跨 CPU 的線程/進程切換。
使用大頁內(nèi)存:避免 TLB Cache Miss。
使用 DPDK:DPDK 改造了傳統(tǒng)的協(xié)議棧數(shù)據(jù)包轉(zhuǎn)發(fā)路徑,避免了頻繁的硬件中斷和無效數(shù)據(jù)拷貝。
DPDK
DPDK(Data Plane Development Kit,數(shù)據(jù)平面開發(fā)套件)是一個開源的、快速處理數(shù)據(jù)平面數(shù)據(jù)包轉(zhuǎn)發(fā)的開發(fā)平臺及接口。運行于 Intel x86 與 ARM 平臺上,最新版本也開始支持 PowerPC。
DPDK 提供了一個用戶態(tài)的高效數(shù)據(jù)包處理庫函數(shù),它通過環(huán)境抽象層、旁路內(nèi)核協(xié)議棧、輪詢模式的報文無中斷收發(fā)、優(yōu)化內(nèi)存/緩沖區(qū)/隊列管理、基于網(wǎng)卡多隊列和流識別的負載均衡等多項技術(shù),實現(xiàn)了在 x86 處理器架構(gòu)下的高性能報文轉(zhuǎn)發(fā)能力,用戶可以在 Linux 用戶態(tài)開發(fā)各類高速轉(zhuǎn)發(fā)應用,也適合與各類商業(yè)化的數(shù)據(jù)平面加速解決方案進行集成。簡而言之,DPDK 重載了網(wǎng)卡驅(qū)動,將數(shù)據(jù)包的控制平面和數(shù)據(jù)平面分離,驅(qū)動在收到數(shù)據(jù)包后不再硬中斷通知 CPU,而是讓數(shù)據(jù)包通過旁路的內(nèi)核協(xié)議棧繞過了 Linux 內(nèi)核協(xié)議棧,并通過零拷貝技術(shù)存入內(nèi)存,這時應用層的程序就可以通過 DPDK 提供的接口,直接從內(nèi)存讀取數(shù)據(jù)包。
DPDK 數(shù)據(jù)包處理流程:
這種處理方式節(jié)省了 CPU 中斷時間、內(nèi)存拷貝時間,并向應用層提供了簡單易行且高效的數(shù)據(jù)包處理方式,使得網(wǎng)絡應用的開發(fā)更加方便。但同時,由于需要重載網(wǎng)卡驅(qū)動,因此該開發(fā)包目前只能用在部分采用 Intel 網(wǎng)絡處理芯片的網(wǎng)卡中。DPDK 可以將數(shù)據(jù)包處理性能最多提高十倍。在單個英特爾至強處理器上獲得超過 80 Mbps 的吞吐量,在雙處理器配置中則可將該其提高一倍。
英特爾在 2010 年啟動了對 DPDK 技術(shù)的開源化進程,于當年 9 月通過 BSD 開源許可協(xié)議正式發(fā)布源代碼軟件包,并于 2014 年 4 月在 www.dpdk.org 上正式成立了獨立的開源社區(qū)平臺,為開發(fā)者提供支持。開源社區(qū)的參與者們大幅推進了 DPDK 的技術(shù)創(chuàng)新和快速演進,而今它已發(fā)展成為 SDN 和 NFV 的一項關(guān)鍵技術(shù)。
DPDK 基本技術(shù)
DPDK 基本技術(shù)指標準的 DPDK 數(shù)據(jù)平面開發(fā)包和 I/O 轉(zhuǎn)發(fā)實現(xiàn)技術(shù)。我們首先從 DPDK 的架構(gòu)入手,再逐一解析 DPDK 的核心技術(shù)。
DPDK 架構(gòu)
在最底部的內(nèi)核態(tài)(Linux Kernel)DPDK 有兩個模塊:KNI 與 IGB_UIO。其中,KNI 提供給用戶一個使用 Linux 內(nèi)核態(tài)的協(xié)議棧,以及傳統(tǒng)的 Linux 網(wǎng)絡工具(e.g. ethtool、ifconfig)。IGB_UIO(igb_uio.ko 和 kni.ko.IGB_UIO)則借助了 UIO 技術(shù),在初始化過程中將網(wǎng)卡硬件寄存器映射到用戶態(tài)。
UIO:是用戶態(tài)的一種 I/O 技術(shù),DPDK 能夠繞過內(nèi)核協(xié)議棧,本質(zhì)是得益于 UIO 技術(shù),通過 UIO 能夠攔截中斷,并重設中斷回調(diào)行為,從而繞過內(nèi)核協(xié)議棧后續(xù)的處理流程。UIO 的實現(xiàn)機制其實是對用戶態(tài)暴露文件接口,比如當注冊一個 UIO 設備 uioX,就會出現(xiàn)文件 /dev/uioX,對該文件的讀寫就是對設備內(nèi)存的讀寫。除此之外,對設備的控制還可以通過 /sys/class/uio 下的各個文件的讀寫來完成。
DPDK 的上層用戶態(tài)由很多庫組成,主要包括核心部件庫(Core Libraries)、平臺相關(guān)模塊(Platform)、網(wǎng)卡輪詢模式驅(qū)動模塊(PMD-Natives&Virtual)、QoS 庫、報文轉(zhuǎn)發(fā)分類算法(Classify)等幾大類,用戶應用程序可以使用這些庫進行二次開發(fā)。
核心部件庫:該模塊構(gòu)成的運行環(huán)境是建立在 Linux 上,通過環(huán)境抽象層(EAL)的運行環(huán)境進行初始化,包括:HugePage 內(nèi)存分配、內(nèi)存/緩沖區(qū)/隊列分配與無鎖操作、CPU 親和性綁定等;其次,EAL 實現(xiàn)了對操作系統(tǒng)內(nèi)核與底層網(wǎng)卡 I/O 操作的屏蔽(I/O 旁路了內(nèi)核及其協(xié)議棧),為 DPDK 應用程序提供了一組調(diào)用接口,通過 UIO 或 VFIO 技術(shù)將 PCI 設備地址映射到用戶空間,方便了應用程序調(diào)用,避免了網(wǎng)絡協(xié)議棧和內(nèi)核切換造成的處理延遲。另外,核心部件還包括創(chuàng)建適合報文處理的內(nèi)存池、緩沖區(qū)分配管理、內(nèi)存拷貝、以及定時器、環(huán)形緩沖區(qū)管理等。
EAL(Environment Abstraction Layer,環(huán)境抽象層):為應用提供了一個通用接口,隱藏了與底層庫與設備打交道的相關(guān)細節(jié)。EAL 實現(xiàn)了 DPDK 運行的初始化工作,例如:基于大頁表的內(nèi)存分配,多核親和性設置,原子性和鎖操作,并將 PCI 設備地址映射到用戶空間,方便應用程序訪問。
MALLOC(堆內(nèi)存管理組件):為應用程序提供從大頁內(nèi)存分配堆內(nèi)存的接口。當需要分配大量小塊內(nèi)存時,如:用于存儲列表中每個表項指針的內(nèi)存,使用這些接口可以減少 TLB 缺頁。
MBUF(網(wǎng)絡報文緩存塊管理組件):為應用程序提供創(chuàng)建和釋放用于存儲報文信息的緩存塊的接口,這些 MBUF 存儲在一內(nèi)存池中。提供兩種類型的 MBUF,一種用于存儲一般信息,一種用于存儲報文數(shù)據(jù)。
Buffer Manager API:通過預先從 EAL 上分配固定大小的多個內(nèi)存對象,避免了在運行過程中動態(tài)進行內(nèi)存分配和回收來提高效率,常常用作數(shù)據(jù)包 Buffer 來使用。
MEMPOOL(內(nèi)存池管理組件):為應用程序和其它組件提供分配內(nèi)存池的接口,內(nèi)存池是一個由固定大小的多個內(nèi)存塊組成的內(nèi)存容器,可用于存儲相同對像實體,如報文緩存塊等。內(nèi)存池由內(nèi)存池的名稱(一個字符串)來唯一標識,它由一個環(huán)緩中區(qū)和一組核本地緩存隊列組成,每個核從自已的緩存隊列分配內(nèi)存塊,當本地緩存隊列減少到一定程度時,從內(nèi)存環(huán)緩沖區(qū)中申請內(nèi)存塊來補充本地隊列。
RING(環(huán)緩沖區(qū)管理組件):為應用程序和其它組件提供一個無鎖的多生產(chǎn)者多消費者 FIFO 隊列 API。
Queue Manager API:以高效的方式實現(xiàn)了無鎖的 FIFO 環(huán)形隊列,適合與一個生產(chǎn)者多個消費者、一個消費者多個生產(chǎn)者模型來避免等待,并且支持批量無鎖的操作。
TIMER(定時器組件):提供一些異步周期執(zhí)行的接口(也可以只執(zhí)行一次),可以指定某個函數(shù)在規(guī)定的時間異步的執(zhí)行,就像 LIBC 中的 timer 定時器,但是這里的定時器需要應用程序在主循環(huán)中周期調(diào)用 rte_timer_manage 來使定時器得到執(zhí)行,使用起來沒有那么方便。定時器組件的時間參考來自 EAL 層提供的時間接口。
Flow Classification API:通過 Intel SSE 基于多元組實現(xiàn)了高效的 hash 算法,以便快速的將數(shù)據(jù)包進行分類處理。該 API 一般用于路由查找過程中的最長前綴匹配中,安全產(chǎn)品中根據(jù) DataFlow 五元組來標記不同用戶的場景也可以使用。
平臺相關(guān)模塊:其內(nèi)部模塊主要包括 KNI、能耗管理以及 IVSHMEM 接口。其中,KNI 模塊主要通過 kni.ko 模塊將數(shù)據(jù)報文從用戶態(tài)傳遞給內(nèi)核態(tài)協(xié)議棧處理,以便用戶進程使用傳統(tǒng)的 Socket 接口對相關(guān)報文進行處理;能耗管理則提供了一些 API,應用程序可以根據(jù)收包速率動態(tài)調(diào)整處理器頻率或進入處理器的不同休眠狀態(tài);另外,IVSHMEM 模塊提供了虛擬機與虛擬機之間,或者虛擬機與主機之間的零拷貝共享內(nèi)存機制,當 DPDK 程序運行時,IVSHMEM 模塊會調(diào)用核心部件庫 API,把幾個 HugePage 映射為一個 IVSHMEM 設備池,并通過參數(shù)傳遞給 QEMU,這樣,就實現(xiàn)了虛擬機之間的零拷貝內(nèi)存共享。
輪詢模式驅(qū)動模塊:PMD 相關(guān) API 實現(xiàn)了在輪詢方式下進行網(wǎng)卡報文收發(fā),避免了常規(guī)報文處理方法中因采用中斷方式造成的響應延遲,極大提升了網(wǎng)卡收發(fā)性能。此外,該模塊還同時支持物理和虛擬化兩種網(wǎng)絡接口,從僅僅支持 Intel 網(wǎng)卡,發(fā)展到支持 Cisco、Broadcom、Mellanox、Chelsio 等整個行業(yè)生態(tài)系統(tǒng),以及基于 KVM、VMWARE、 XEN 等虛擬化網(wǎng)絡接口的支持。
PMD(Poll Mode Drivers):實現(xiàn)了 Intel 1GbE、10GbE 和 40GbE 網(wǎng)卡下基于輪詢收發(fā)包的工作模式,大大加速網(wǎng)卡收發(fā)包性能。
DPDK 核心組件
Memory Manager(librte_malloc,內(nèi)存管理器):提供一組 API,用于從 HugePages 創(chuàng)建的 memzones 中分配內(nèi)存而不是在堆中分配。這有助于改善 Linux 用戶態(tài)環(huán)境下典型的從堆中大量分配 4KB 頁面而容易引起 TLB miss。
Ring Manager(librte_ring,環(huán)形隊列管理器):在一個有限大小的頁表中,Ring 數(shù)據(jù)結(jié)構(gòu)提供了一個無鎖的多生產(chǎn)者,多消費者的 FIFO API。相較于無鎖隊列,它有一些的優(yōu)勢,如:更容易實現(xiàn),適應于大容量操作,而且速度更快。 Ring 在 Memory Pool Manager 中被使用,而且 Ring 還用于不同 Core 之間或是 Processor 上處理單元之間的通信。
Memory Pool Manager(librte_mempool,內(nèi)存池管理器):內(nèi)存池管理器負責分配的內(nèi)存中的 Pool 對象。Pool 由名稱唯一標識,并使用一個 Ring 來存儲空閑對象。它提供了其他一些可選的服務,例如:每個 Core 的對象緩存和對齊方式幫助器,以確保將填充的對象在所有內(nèi)存通道上均勻分布。
Network Packet Buffer Management(librte_mbuf,網(wǎng)絡報文緩沖管理):提供了創(chuàng)建和銷毀數(shù)據(jù)包緩沖區(qū)的能力。DPDK 應用程序中可以使用這些緩存區(qū)來存儲消息。應用程序通常在啟動時通過 DPDK 的 Memory Pool Manager 庫創(chuàng)建并存儲。
Timer Manager(librte_timer,定時器管理):為 DPDK 執(zhí)行單元提供了定時服務,為函數(shù)異步執(zhí)行提供支持。定時器可以設置周期調(diào)用或只調(diào)用一次。應用程序可以使用 EAL 提供的接口獲取高精度時鐘,并且能在每個核上根據(jù)需要進行初始化。
注:
RTE:Run-Time Environment
EAL:Environment Abstraction Layer
PMD:Poll-Mode Driver
應用 NUMA 親和性技術(shù)減少跨 NUMA 內(nèi)存訪問
在 NUMA(Non-Uniform Memory Access,非一致性存儲器訪問)架構(gòu)的處理機中,CPU 訪問本地內(nèi)存(同 NUMA)和遠程內(nèi)存(跨 NUMA)的耗時并不相同,NUMA “非一致性存儲器訪問” 架構(gòu)由此得名。
NUMA 的結(jié)構(gòu)設計能夠在一定程度上解決 SMP 低存儲器訪問帶寬的問題。假如一個 4 NUMA 節(jié)點的系統(tǒng),每一個 NUMA 節(jié)點內(nèi)部都具有 1GB/s 的存儲帶寬,外部共享總線也同樣具有 1GB/s 的帶寬。理想狀態(tài)下,如果所有的 CPU 總是訪問本地內(nèi)存的話,那么系統(tǒng)就擁有了 4GB/s 的存儲帶寬能力。此時的每個 NUA 節(jié)點都可以近似的看作為一個 SMP(這種假設為了便于理解,并不完全正確);相反,在最不理想的情況下,如果所有處理器總是訪問遠程內(nèi)存的話,那么系統(tǒng)就只能有 1GB/s 的存儲器訪問帶寬。
除此之外,使用外部共享總線時可能會觸發(fā) NUMA 節(jié)點間的 Cache 同步損耗,這會嚴重影響內(nèi)存密集型工作負載的性能。當 I/O 性能至關(guān)重要時,外部共享總線上的 Cache 資源浪費,會讓連接到遠程 PCIe 總線上的設備(不同 NUMA 節(jié)點間通信)作業(yè)性能急劇下降。
由于這個特性,基于 NUMA 架構(gòu)開發(fā)的應用程序應該盡可能避免跨 NUMA 節(jié)點的遠程內(nèi)存訪問。因為,跨節(jié)點內(nèi)存訪問不僅通信速度慢,還可能需要處理不同節(jié)點間內(nèi)存、緩存的數(shù)據(jù)一致性問題。多線程在不同 NUMA 節(jié)點間的切換,是需要花費大成本的。
應用 CPU 綁核技術(shù)減少上下文切換損耗
現(xiàn)代操作系統(tǒng)都是基于分時調(diào)用方式來實現(xiàn)任務調(diào)度,多個進程或線程在多核處理器的某一個核上不斷地交替執(zhí)行。每次切換過程,都需要將處理器的狀態(tài)寄存器保存在堆棧中,并恢復當前進程的狀態(tài)信息,這對系統(tǒng)其實是一種處理開銷。將一個線程固定一個核上運行,可以消除切換帶來的額外開銷。另外將進程或者線程遷移到多核處理器的其它核上進行運行時,處理器緩存中的數(shù)據(jù)也需要進行清除,導致處理器緩存的利用效果降低
CPU 親和技術(shù),就是將某個進程或者線程綁定到特定的一個或者多個核上執(zhí)行,而不被遷移到其它核上運行,這樣就保證了專用程序的性能。DPDK 使用了 Linux pthread 庫,在系統(tǒng)中把相應的線程和 CPU 進行親和性綁定,然后相應的線程盡可能使用獨立的資源進行相關(guān)的數(shù)據(jù)處理。
應用大頁內(nèi)存技術(shù)減少 TLB miss
處理器的內(nèi)存管理包含兩個概念:物理內(nèi)存和虛擬內(nèi)存。Linux 操作系統(tǒng)里面整個物理內(nèi)存按幀(Frames)來進行管理,虛擬內(nèi)存按照頁(Page)來進行管理。內(nèi)存管理單元(MMU)完成從虛擬內(nèi)存地址到物理內(nèi)存地址的轉(zhuǎn)換。內(nèi)存管理單元進行地址轉(zhuǎn)換需要的信息保存在
一個叫頁表(Page Table)的數(shù)據(jù)結(jié)構(gòu)里面,頁表查找是一種極其耗時的操作。為了減少頁表的查找過程,Intel 處理器實現(xiàn)了一塊緩存來保存查找結(jié)果,這塊緩存被稱為 TLB(Translation Lookaside Buffer),它保存了虛擬地址到物理地址的映射關(guān)系。所有虛擬地址在轉(zhuǎn)換為物理地址以前,處理器會首先在 TLB 中查找是否已經(jīng)存在有效的映射關(guān)系,如果沒有發(fā)現(xiàn)有效的映射,也就是 TLS miss,處理器再進行頁表的查找。頁表的查找過程對性能影響極大,因此需要盡量減少 TLB miss 的發(fā)生。
x86 處理器硬件在缺省配置下,頁的大小是 4K,但也可以支持更大的頁表尺寸,例如 2M 或 1G 的頁表。使用了大頁表功能后,一個 TLB 表項可以指向更大的內(nèi)存區(qū)域,這樣可以大幅減少 TLB miss 的發(fā)生。早期的 Linux 并沒有利用 x86 硬件提供的大頁表功能,僅在 Linux 內(nèi)核 2.6.33 以后的版本,應用軟件才可以使用大頁表功能。DPDK 則利用大頁技術(shù),所有的內(nèi)存都是從 HugePage 里分配,實現(xiàn)對內(nèi)存池(Mempool)的管理,并預先分配好同樣大小的 mbuf,供每一個數(shù)據(jù)包使用。
DPDK 目前支持了 2M 和 1G 兩種 HugePage。通過編輯 /etc/grub.conf 來設置:
default_hugepagesz=1G hugepagesz=1G hugepages=32 isolcpus=0-22
然后,執(zhí)行下述指令,將 HugePage 文件系統(tǒng) hugetlbfs 掛載到 /mnt/huge 目錄:
mount –t hugetlbfs nodev /mnt/huge
如此,用戶進程就可以使用 mmap() 系統(tǒng)調(diào)用映射 HugePage 目標文件來使用大頁面了。測試表明應用程序使用大頁表比使用 4K 的小頁表性能提高 10%~15%。
NOTE:大頁內(nèi)存的具體介紹可以參見 Linux 的大頁表文件系統(tǒng)(hugetlbfs)特性。
應用 PMD 輪詢技術(shù)減少網(wǎng)卡外設的硬件中斷
傳統(tǒng)網(wǎng)卡的報文接收/發(fā)送過程中,網(wǎng)卡硬件收到網(wǎng)絡報文,或發(fā)送完網(wǎng)絡報文后,需要發(fā)送中斷到 CPU,通知應用軟件有網(wǎng)絡報文需要處理。在 x86 處理器上,一次中斷處理需要將處理器的狀態(tài)寄存器保存到堆棧,并運行中斷服務程序,最后再將保存的狀態(tài)寄存器信息從堆棧中恢復。整個過程需要至少 300 個處理器時鐘周期。對于高性能網(wǎng)絡處理應用,頻繁的中斷處理開銷極大降低了網(wǎng)絡應用程序的性能。
為了減少中斷處理開銷,DPDK 使用了輪詢技術(shù)來處理網(wǎng)絡報文,網(wǎng)卡收到報文后,可以借助 DDIO(Direct Data I/O)技術(shù)直接將報文保存到處理器 Cache 中,或者保存到內(nèi)存中(沒有 DDIO 技術(shù)的情況下),并設置報文到達的標志位。應用軟件則周期性地輪詢報文到達的標志位,檢測是否有新報文需要處理。整個過程中完全沒有中斷處理過程,因此應用程序的網(wǎng)絡報文處理能力得以極大提升。
針對 Intel 網(wǎng)卡,DPDK 實現(xiàn)了基于輪詢方式的 PMD(Poll Mode Drivers)網(wǎng)卡驅(qū)動。該驅(qū)動由 API、用戶空間運行的驅(qū)動程序構(gòu)成,除了鏈路狀態(tài)通知仍必須采用中斷方式以外,均使用無中斷方式直接操作網(wǎng)卡的接收和發(fā)送隊列。目前 PMD 驅(qū)動支持 Intel 的大部分 1G、10G 和 40G 的網(wǎng)卡。
PMD 驅(qū)動從網(wǎng)卡上接收到數(shù)據(jù)包后,會直接通過 DMA 方式傳輸?shù)筋A分配的內(nèi)存中,同時更新無鎖環(huán)形隊列中的數(shù)據(jù)包指針,不斷輪詢的應用程序很快就能感知收到數(shù)據(jù)包,并在預分配的內(nèi)存地址上直接處理數(shù)據(jù)包,這個過程非常簡潔。
應用 UIO 和內(nèi)存池技術(shù)減少內(nèi)存拷貝
如果讓 Linux 來處理收包過程,首先網(wǎng)卡通過中斷方式通知內(nèi)核協(xié)議棧對數(shù)據(jù)包進行處理,內(nèi)核協(xié)議棧先會對數(shù)據(jù)包進行合法性進行必要的校驗,然后判斷數(shù)據(jù)包目標是否本機的 Socket,滿足條件則會將數(shù)據(jù)包拷貝一份向上遞交給用戶態(tài) Socket 來處理,不僅處理路徑冗長,還需要從內(nèi)核到應用層的一次拷貝過程。
DPDK 則利用 UIO 技術(shù),提供了應用空間下 PMD 驅(qū)動程序的支持,也就是說網(wǎng)卡驅(qū)動直接就是運行在用戶空間的,減下了報文在用戶空間和應用空間的多次拷貝。
DPDK 還在用戶空間實現(xiàn)了一套精巧的內(nèi)存池技術(shù),內(nèi)核空間和用戶空間的內(nèi)存交互不進行拷貝,只做控制權(quán)轉(zhuǎn)移。這樣,當收發(fā)數(shù)據(jù)包時,就減少了內(nèi)存拷貝的開銷。
應用無鎖循環(huán)隊列較少鎖操作對 CPU 的開銷
DPDK 基于 Linux 內(nèi)核的無鎖環(huán)形緩沖 kfifo 實現(xiàn)了一套自己的無鎖機制。支持單生產(chǎn)者入列/單消費者出列和多生產(chǎn)者入列/多消費者出列操作,在數(shù)據(jù)傳輸?shù)臅r候,降低性能的同時還能保證數(shù)據(jù)的同步。
DPDK 優(yōu)化技術(shù)
DPDK 優(yōu)化技術(shù)指在 DPDK 應用過程中,為進一步提高各類用戶應用程序的轉(zhuǎn)發(fā)性能,所采取的性能調(diào)優(yōu)方法和關(guān)鍵配置。
DPDK 性能影響因素
本節(jié)主要介紹基于 DPDK 進行應用開發(fā)和環(huán)境配置時,應用程序性能的影響因素以及相應的優(yōu)化調(diào)整方法。這些因素并非必然劣化性能,可能因硬件能力、OS 版本、各類軟硬環(huán)境參數(shù)配置等的差異產(chǎn)生較大波動,或者存在較大的不穩(wěn)定性,相關(guān)的調(diào)優(yōu)方法需要用戶結(jié)合自身的 VNF 應用部署在實踐中不斷完善。
硬件結(jié)構(gòu)的影響
DPDK 具有廣泛的平臺適應性,可以運行在整個 x86 平臺,從主流服務器平臺(從高性能或者高能效產(chǎn)品系列),到桌面或者嵌入式平臺,也可以運行于基于 Power 或者其他架構(gòu)的運算平臺。下圖展示了一個通用雙路服務器的內(nèi)部架構(gòu),它包含了 2 個中央處理器,2 個分離的內(nèi)存控制單元來連接系統(tǒng)內(nèi)存,芯片組會擴展出大量高速的 PCIe 2.0/3.0 接口,用于連接外設,如 10Gbps 或者 25Gbps 網(wǎng)卡外設。
硬件規(guī)格對 DPDK 性能的影響體現(xiàn)在幾個方面:
CPU 頻率:CPU 頻率越高,DPDK 性能越高。
LLC(Last Leve Cache)大小:緩存越大,DPDK 性能越高。
PCIe Lane 的數(shù)目:PCIe 鏈路可以支持 1、2、4、8、12、16 和 32 個 Lane,需要確保其帶寬可以滿足所插網(wǎng)卡的帶寬。
NUMA:網(wǎng)絡數(shù)據(jù)報文的處理由網(wǎng)卡所在的 NUMA 節(jié)點處理,將會比遠端 NUMA 節(jié)點處理的性能更高。
OS 版本及其內(nèi)核的影響
不同的 Linux OS 發(fā)行版使用的 Linux 內(nèi)核版本不一樣,配置的 Linux OS 服務也不一樣。這些差異都會導致應用程序在網(wǎng)絡報文處理能力上有所差別。由于 Linux 內(nèi)核還在不斷演進,Linux 的發(fā)行版也數(shù)量眾多,同樣的硬件配置環(huán)境下,不同的 Linux 發(fā)行版在小包的處理能力上存在差異。本文無法提供最佳 Linux 內(nèi)核版本和配置,而只能給出部分參考建議,如:關(guān)閉部分 OS 服務。
OVS 性能問題
OVS 作為 NFV 的一個重要組成模塊,會運行在絕大多數(shù)的服務器節(jié)點上,提供虛擬機和虛擬機之間,以及虛擬網(wǎng)絡和物理網(wǎng)絡間的互連接口,其性能至關(guān)重要。OVS 2.4 開始正式支持 DPDK 加速,相比傳統(tǒng)基于 Linux 內(nèi)核的 OVS 版本,轉(zhuǎn)發(fā)性能提高了數(shù)倍,為 VNF 在通用 x86 服務器上部署提供了有力支持。
OVS 缺省會為每一個 NUMA 節(jié)點創(chuàng)建一個 pmd 線程,該 pmd 線程以輪詢方式處理屬于其 NUMA 節(jié)點上的所有 DPDK 接口。為了高性能,需要利用前面提到的 CPU 綁核技術(shù),把 pmd 線程綁定在一個固定的 CPU core 上處理。此外,為了增加擴展性,OVS 2.4 也支持網(wǎng)卡多隊列以及多 pmd 線程數(shù),這些參數(shù)均可動態(tài)配置,但具體配置應根據(jù)具體需求來決定。
內(nèi)存管理
如前所述,DPDK 考慮了 NUMA 以及多內(nèi)存通道的訪問效率,會在系統(tǒng)運行前要求配置 Linux 的 HugePage,初始化時申請其內(nèi)存池,用于 DPDK 運行的主要內(nèi)存資源。Linux 大頁機制利用了處理器核上的的 TLB 的 HugePage 表項,這可以減少內(nèi)存地址轉(zhuǎn)換的開銷。
CPU 核間無鎖通信
如果想建立一個基于消息傳遞的核間通信機制,可以使用 DPDK Ring API,它是一個無鎖的 ring 實現(xiàn)。該 Ring 機制支持批量和突發(fā)訪問,即使同時讀取幾個對象,也只需要一個昂貴的原子操作,批量訪問可以極大地改善性能。
設置正確的目標 CPU 類型與模式
DPDK 支持 CPU 微架構(gòu)級別的優(yōu)化,可以通過修改 DPDK 配置文件中的 CONFIG_RTE_MACHINE 參數(shù)來定義。優(yōu)化的程度根據(jù)隨編譯器的能力而不同,通常建議采用最新的編譯器進行編譯。如果編譯器的版本不支持該款 CPU 的特性,比如 Intel AVX 指令,那么它在編譯時只會選用自己支持的指令集,這可能導致編譯后生成的 DPDK 應用的性能下降。
優(yōu)化方案
筆者在 DPDK 的優(yōu)化方面的實踐因為商業(yè)敏感的問題,本文不便提及。網(wǎng)上有很多資料,推薦閱讀這一篇文章 https://zhaozhanxu.com/2016/08/09/DPDK/2016-08-09-dpdk-optimization/ 和《DPDK 技術(shù)白皮書》。
DPDK 在 NFV 中的應用
ETSI NFV 技術(shù)通過運行在通用 x86 架構(gòu)硬件上的虛擬化網(wǎng)絡功能,為電信運營商和互聯(lián)網(wǎng)服務商提供了一種靈活的業(yè)務部署手段和高效的組網(wǎng)方案,可以支持固移網(wǎng)絡和 IDC 中 NAT、DPI、EPC、FW 等各類業(yè)務功能的廣域靈活部署與網(wǎng)元彈性擴展。
不同于典型數(shù)據(jù)中心業(yè)務和企業(yè)網(wǎng)業(yè)務,電信廣域網(wǎng)業(yè)務要求網(wǎng)元(如 BNG、DPI 等)具有高吞吐、低時延、海量流表支持、用戶級 QoS 控制的特點。大量實踐表明,通用 x86 服務器作為 NFV 基礎(chǔ)設施用于高轉(zhuǎn)發(fā)業(yè)務時,面臨著嚴重的轉(zhuǎn)發(fā)性能瓶頸,需要有針對性地從硬件架構(gòu)、系統(tǒng) I/O、操作系統(tǒng)、虛擬化層、組網(wǎng)與流量調(diào)度、VNF 功能等層面進行性能優(yōu)化,才能達到各類 NFV 網(wǎng)絡業(yè)務的高性能轉(zhuǎn)發(fā)要求。
根據(jù) ETSI 的 NFV 參考架構(gòu),現(xiàn)實中的 NFV 應用系統(tǒng)一般由 NFV 基礎(chǔ)設施和 VNF 兩類系統(tǒng)服務商提供。因此,相應的 NFV 端到端性能測試,也應劃分為底層的 NFV 基礎(chǔ)設施性能與上層的 VNF 性能兩類,以明確各自的性能瓶頸,并避免性能調(diào)優(yōu)工作相互干擾。
在 NFV 基礎(chǔ)設施性能層面,由于采用軟件轉(zhuǎn)發(fā)和軟件交換技術(shù),單個物理服務器內(nèi)部的轉(zhuǎn)發(fā)能力是 NFV 系統(tǒng)的主要性能瓶頸。在各類高速轉(zhuǎn)發(fā)的 NFV 應用中,數(shù)據(jù)報文從網(wǎng)卡中接收,再傳送到虛擬化的用戶態(tài)應用程序(VNF)處理。整個過程要經(jīng)歷 CPU 中斷處理、虛擬化 I/O 與地址映射轉(zhuǎn)換、虛擬交換層、內(nèi)核協(xié)議棧、內(nèi)核上下文切換、內(nèi)存拷貝等多個費時的 CPU 操作和 I/O 處理環(huán)節(jié)。面對這樣的性能損耗問題,業(yè)內(nèi)通常采用消除海量中斷、旁路內(nèi)核協(xié)議棧、減少內(nèi)存拷貝、CPU 多核任務分擔、Intel VT 等技術(shù)來綜合提升服務器數(shù)據(jù)平面的報文處理性能。但由于技術(shù)棧復雜,普通用戶較難掌握,業(yè)界迫切需要一種綜合的性能優(yōu)化方案,同時提供良好的用戶開發(fā)和商業(yè)集成環(huán)境。
在各類 NFV 基礎(chǔ)設施性能優(yōu)化技術(shù)方案中,DPDK 加速技術(shù)方案成為其中的典型代表。DPDK 以用戶數(shù)據(jù) I/O 通道優(yōu)化為基礎(chǔ),結(jié)合了 Intel VT 技術(shù)、操作系統(tǒng)、虛擬化層與 vSwitch 等多種優(yōu)化方案,已經(jīng)形成了完善的性能加速整體架構(gòu),并提供了用戶態(tài) API 供高速轉(zhuǎn)發(fā)類應用訪問。
參考文章
https://vcpu.me/packet_from_nic_to_user_process/
https://blog.csdn.net/City_of_skey/article/details/85038684
https://blog.csdn.net/qq_15437629/article/details/78146823
https://zhaozhanxu.com/2016/08/09/DPDK/2016-08-09-dpdk-optimization/
https://mp.weixin.qq.com/s/RW0GO8hNxoE7upAeAExWHg
總結(jié)
以上是生活随笔為你收集整理的DPDK 网络加速在 NFV 中的应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 农行信用币怎么注销?关闭农行信用币的方法
- 下一篇: JS ajax请求参数格式( formD