本文為作者原創,轉載請注明出處(http://www.cnblogs.com/mar-q/)by 負贔屓
對筆者而言,這是一個挺新的領域,比較有意思。
一、解釋名詞:
NFV(Network Function Virtualization):通過使用x86等通用性硬件以及虛擬化技術,來承載很多功能的軟件處理。從而降低網絡昂貴的設備成本。 這項技術的目的在於軟硬件的解耦合,讓網絡設備功能不再依賴於底層硬件,為啥呢,因為硬件研發周期長,貴啊。
DPDK(Intel Data Plane Development Kit):Intel數據面開發包,它是一組快速處理數據包的開發平台接口。
二、我們的網絡存在什么問題?
目前服務器並發量達到C10k是沒有問題的,通過軟件作出了比較好的解決方案,例如Nginx、Lighthttp等基於事件驅動的web框架和Tornado這類非阻塞web框架,都能夠較好的解決萬級別的用戶請求。目前的非阻塞或者異步,原理上都是線程的異步模式,也就是說還是需要線程進行上下文切換,只不過區別在於內核何時產生中斷。
但是這種異步模式到了C10M基本就不夠用了,網絡請求達到了千萬級,這在以前也許是網絡設備廠商需要考慮的事情,隨着硬件設備的發展,越來越趨於模塊的統一化。例如曾經網絡專用處理器是Intel公司的主力產品線,誕生了IXP4xx~IXP28xx等一系列專用處理芯片,而在2006年左右,AMD和Intel曾經爆發過一場多核之戰,隨着新一代core架構的誕生(Intel要感謝以色列的工程師),這場戰爭基本宣告結束,但是在當時,AMD在技術上曾經一度領先,我的第一台電腦CPU就是AMD的。這次商業大戰讓Intel思考使用通用多核處理器取代IXP專用處理器,由此IXP的研發體系開始向Intel多核CPU轉型,這為DPDK的誕生創造了條件。
為啥為Intel向通用CPU轉型就會產生DPDK呢,因為使用通用的底層硬件我們就可以不必太關注底層,大家都是用的X86,都是用的RISC,所以更多的功能可以放在軟件層面來完成,尤其是硬件開發成本和周期是遠遠超過軟件的,所以何樂而不為呢。再回到前面的問題,為什么異步解決不了C10M的問題呢?因為線程的頻繁調度是需要內核進行上下文切換的,而CPU是存在指令周期的,尤其是當Cache不命中的時候,切換上下文的指令周期會延長很多,要解決這個問題就要避開這種中斷模式:即采用輪詢的方式來提升性能。
從數據包角度分析:這就要求我們必須繞開現有的內核協議,因為現有的內核協議棧是基於中斷模式的,如果要繞開內核,那就要解決驅動問題,解決網卡接口數據怎么到內存的問題,這些就是DPDK所提供的功能。
從多核角度分析:要盡量減少線程的調度和切換,最好每個OS進程綁定一個核,每個核上數據結構都大致相同,在NUMA架構(非一致性訪存體系結構,分多節點,每個節點多個CPU,內部共享一個內存控制器)下提高訪存速度。
從內存角度分析:要盡量減少Cache miss,如果每個用戶占用2k空間,10M的用戶將使用20g內存,這么多並發連接一定會產生Cache miss,一旦失效CPU運行時間會提高一個數量級,因此我們可以通過大頁的方法,盡量把內存划分更少的塊數,以此提高命中率。
綜上,千萬級數據包的處理思路就是:摒棄內核協議(PF_RING,Netmap,intelDPDK)、多核的OS綁定、內存大頁。[1]
三、用戶態協議
傳統X86架構網絡數據包處理是CPU中斷方式:網卡驅動接收數據包->中斷通知CPU處理->CPU拷貝數據並交給協議棧,當數據量大時會產生大量CPU中斷,導致CPU無法運行其他程序。DPDK采用輪詢方式處理:DPDK重載網卡驅動(接管網卡),DPDK接收數據包后不中斷,直接將數據包通過零拷貝技術存入內存,應用層直接通過DPDK接口直接從內存讀取數據包。 DPDK目前正在成為實現NFV的一項標桿技術,它主要為Intel architecture(IA)處理器架構下用戶空間高效的數據包處理提供庫函數和驅動的支持,它不同於Linux系統以通用性設計為目的,而是專注於網絡應用中數據包的高性能處理,運行在用戶空間上利用自身提供的數據平面庫來收發數據包,繞過了Linux內核協議棧對數據包處理過程。[2]
需要注意的是,DPDK本身並不是一項協議,它不提供諸如IP協議、防火牆等網絡協議功能,它只是我們在OS下的一套數據處理接口。因為多年來,高性能網絡背后的傳統思想就是將所有的數據包處理功能,盡可能的推向內核,數據報傳輸時需要跨越內核和用戶,數據報中斷產生的上下文切換和數據復制的成本都極大限制了數據報文處理的速度,所以我們可以用DPDK來繞過內核,這就是用戶態協議要完成的工作。
為啥叫用戶態協議呢?它和現有的TCP/IP協議有什么區別呢?簡而言之就是現有的TCP/IP協議都是基於內核運行的,而用戶態協議就是另外開發一套協議運行於內核之外。自2014年起在OSDI、NSDI、TOCS 等頂會期刊上出現了不少用戶態協議,列舉如下:
1. IX Project:Stanford & EPFL git、論文地址
IX是一個專門的數據面lib OS,解決了高吞吐量,低延遲,強大的保護和能源效率之間的4路權衡。IX使用硬件虛擬化將控制面與數據面分開,從而保持現有內核的健壯性。控制面負責資源分配,數據面負責提供高性能網絡I / O。通過對事件驅動關鍵應用的延遲和吞吐量進行優化,主要方法是按批次綁定處理數據包,最小化這些連續傳輸,並保持多核同步。 IX的團隊則認為不應信任那些直接訪問設備的應用,一方面擔心應用的穩定性,另一方面這種方式對網絡安全產生的巨大威脅。因此IX通過Intel虛擬化擴展讓I/O路徑和應用程序代碼共存,將隊列映射到內核,但是仍然設法在隔離的保護域中運行網絡堆棧,在這個隔離的保護域中,應用程序不能使用數據。
簡而言之,IX自己實現了一個叫dune的安全核,因為需要使用硬件虛擬化,所以IX目前支持的網卡有限,我后續會發布測試的文章。
2. mTCP:KAIST(韓)git、論文地址
mTCP是一個基於多核的高性能用戶態協議,這個團隊認為由於內核和用戶空間之間移動數據所采取的機制(如數據拷貝和上下文切換),內核正在阻礙實現良好可擴展的網絡性能,所以他們完全拋棄內核,利用新的網卡NIC和CPU功能(如multiqueue),將設備驅動程序和網絡堆棧直接移入應用程序,並將內核完全從IO路徑中取出。
3. Arrakis:git
做法和mTCP類似,它不僅在應用數據上繞過了內核,它不僅對網絡數據包進行內核屏蔽,對數據存儲也進行了屏蔽。
4. Sandstorm:論文地址 比mTCP在層和API方面更深入一些,它保留了到客戶端應用程序的POSIX套接字接口,盡管它們被重新編譯鏈接到mTCP而不是網絡的libc,它還實現了一個用戶級堆棧,對網絡代碼進行特定應用調整,為Web和DNS服務器實現提供加速。
5. 國內的幾個大的用戶態協議棧
- DPDK-ANS,類似mTCP,他們和阿里走得比較近,已經開始商業運作了,但是開源不是很多:git傳送
- f-stack,騰訊一個團隊開發的用戶態協議棧,使用了FreeBSD:git傳送
四、其他解決方案
上面的分析我們可以看到,主要瓶頸就是內核,繞過內核就能夠獲更高的性能,安全性咋辦呢,IX似乎更好一些,他們的項目中集成了一個dune的系統,這套系統類似於一個安全殼,也就是他們所言的dataplane operating system,dune這個項目是10年就開始做的,所以他們相當於是搞了一套結合運用。
我在跑這套項目的時候還注意到了另一套標准RDMA(Remote Direct Memory Access)遠程直接數據存取,就是為了解決網絡傳輸中服務器端數據處理的延遲而產生的。RDMA這種技術以前只能運行在專用網絡下(例如超算平台),為了將這種技術用在以太網環境下,就逐步發展出了RoCE/iWarp兩種協議。RoCE目前主要是由Mellonax主導(以色列一家專注高性能網絡設備研發的公司),和TCP協議無關,性能更好。iWarp主要由Chelsio主導,下層會依賴TCP協議,性能和可擴性行都差一些,優點是考慮了對廣域網的支持。目前來看RoCE比iWarp前景更好,實際使用也更廣泛。對比DPDK,DPDK是Intel主導,提供了基於用戶態的數據鏈路層的功能,可以在上面構建出基於用戶態的網絡棧。實際使用中一個顯然的缺點是只有poll功能,沒有陷入中斷來減少對CPU的消耗。明顯RDMA偏專用線路(需要專用網卡支持),DPDK則走通用路線(Intel自己就搞定了)。[3]