DPDK 全面分析

https://www.cnblogs.com/bakari/p/8404650.html [轉]

高性能網絡技術

隨着雲計算產業的異軍突起,網絡技術的不斷創新,越來越多的網絡設備基礎架構逐步向基於通用處理器平臺的架構方向融合,從傳統的物理網絡到虛擬網絡,從扁平化的網絡結構到基於 SDN 分層的網絡結構,無不體現出這種創新與融合。

這在使得網絡變得更加可控制和成本更低的同時,也能夠支持大規模用戶或應用程序的性能需求,以及海量數據的處理。究其原因,其實是高性能網絡編程技術隨着網絡架構的演進不斷突破的一種必然結果。

C10K 到 C10M 問題的演進

如今,關注的更多是 C10M 問題(即單機 1 千萬個併發連接問題)。很多計算機領域的大佬們從硬件上和軟件上都提出了多種解決方案。從硬件上,比如說,現在的類似很多 40Gpbs、32-cores、256G RAM 這樣配置的 X86 服務器完全可以處理 1 千萬個以上的併發連接。
但是從硬件上解決問題就沒多大意思了,首先它成本高,其次不通用,最後也沒什麼挑戰,無非就是堆砌硬件而已。所以,拋開硬件不談,我們看看從軟件上該如何解決這個世界難題呢?

這裏不得不提一個人,就是 Errata Security 公司的 CEO Robert Graham,他在 Shmoocon 2013 大會上很巧妙地解釋了這個問題。有興趣可以查看其 YouTube 的演進視頻:C10M Defending The Internet At Scale

他提到了 UNIX 的設計初衷其實爲電話網絡的控制系統而設計的,而不是一般的服務器操作系統,所以,它僅僅是一個負責數據傳送的系統,沒有所謂的控制層面和數據層面的說法,不適合處理大規模的網絡數據包。最後他得出的結論是:

OS 的內核不是解決 C10M 問題的辦法,恰恰相反 OS 的內核正式導致 C10M 問題的關鍵所在。

爲什麼這麼說?基於 OS 內核的數據傳輸有什麼弊端?

1、中斷處理。當網絡中大量數據包到來時,會產生頻繁的硬件中斷請求,這些硬件中斷可以打斷之前較低優先級的軟中斷或者系統調用的執行過程,如果這種打斷頻繁的話,將會產生較高的性能開銷。

2、內存拷貝。正常情況下,一個網絡數據包從網卡到應用程序需要經過如下的過程:數據從網卡通過 DMA 等方式傳到內核開闢的緩衝區,然後從內核空間拷貝到用戶態空間,在 Linux 內核協議棧中,這個耗時操作甚至佔到了數據包整個處理流程的 57.1%。

3、上下文切換。頻繁到達的硬件中斷和軟中斷都可能隨時搶佔系統調用的運行,這會產生大量的上下文切換開銷。另外,在基於多線程的服務器設計框架中,線程間的調度也會產生頻繁的上下文切換開銷,同樣,鎖競爭的耗能也是一個非常嚴重的問題。

4、局部性失效。如今主流的處理器都是多個核心的,這意味着一個數據包的處理可能跨多個 CPU 核心,比如一個數據包可能中斷在 cpu0,內核態處理在 cpu1,用戶態處理在 cpu2,這樣跨多個核心,容易造成 CPU 緩存失效,造成局部性失效。如果是 NUMA 架構,更會造成跨 NUMA 訪問內存,性能受到很大影響。

5、內存管理。傳統服務器內存頁爲 4K,爲了提高內存的訪問速度,避免 cache miss,可以增加 cache 中映射表的條目,但這又會影響 CPU 的檢索效率。

綜合以上問題,可以看出內核本身就是一個非常大的瓶頸所在。那很明顯解決方案就是想辦法繞過內核。
解決方案探討

針對以上弊端,分別提出以下技術點進行探討。

1、控制層和數據層分離。將數據包處理、內存管理、處理器調度等任務轉移到用戶空間去完成,而內核僅僅負責部分控制指令的處理。這樣就不存在上述所說的系統中斷、上下文切換、系統調用、系統調度等等問題。

2、使用多核編程技術代替多線程技術,並設置 CPU 的親和性,將線程和 CPU 核進行一比一綁定,減少彼此之間調度切換。

3、針對 NUMA 系統,儘量使 CPU 核使用所在 NUMA 節點的內存,避免跨內存訪問。

4、使用大頁內存代替普通的內存,減少 cache-miss。

5、採用無鎖技術解決資源競爭問題。

經很多前輩先驅的研究,目前業內已經出現了很多優秀的集成了上述技術方案的高性能網絡數據處理框架,如 6wind、windriver、netmap、dpdk 等,其中,Intel 的 dpdk 在衆多方案脫穎而出,一騎絕塵。

dpdk 爲 Intel 處理器架構下用戶空間高效的數據包處理提供了庫函數和驅動的支持,它不同於 Linux 系統以通用性設計爲目的,而是專注於網絡應用中數據包的高性能處理。

也就是 dpdk 繞過了 Linux 內核協議棧對數據包的處理過程,在用戶空間實現了一套數據平面來進行數據包的收發與處理。在內核看來,dpdk 就是一個普通的用戶態進程,它的編譯、連接和加載方式和普通程序沒有什麼兩樣。
dpdk 的突破

相對傳統的基於內核的網絡數據處理,dpdk 對從內核層到用戶層的網絡數據流程進行了重大突破,我們先看看傳統的數據流程和 dpdk 中的網絡流程有什麼不同。

傳統 Linux 內核網絡數據流程:

硬件中斷—>取包分發至內核線程—>軟件中斷—>內核線程在協議棧中處理包—>處理完畢通知用戶層
用戶層收包–>網絡層—>邏輯層—>業務層

dpdk 網絡數據流程:

硬件中斷—>放棄中斷流程
用戶層通過設備映射取包—>進入用戶層協議棧—>邏輯層—>業務層

下面就具體看看 dpdk 做了哪些突破?

UIO (用戶空間的 I/O 技術)的加持。

dpdk 能夠繞過內核協議棧,本質上是得益於 UIO 技術,通過 UIO 能夠攔截中斷,並重設中斷回調行爲,從而繞過內核協議棧後續的處理流程。

UIO 設備的實現機制其實是對用戶空間暴露文件接口,比如當註冊一個 UIO 設備 uioX,就會出現文件 /dev/uioX,對該文件的讀寫就是對設備內存的讀寫。除此之外,對設備的控制還可以通過 /sys/class/uio 下的各個文件的讀寫來完成。
在這裏插入圖片描述
內存池技術

dpdk 在用戶空間實現了一套精巧的內存池技術,內核空間和用戶空間的內存交互不進行拷貝,只做控制權轉移。這樣,當收發數據包時,就減少了內存拷貝的開銷。

大頁內存管理

dpdk 實現了一組大頁內存分配、使用和釋放的 API,上層應用可以很方便使用 API 申請使用大頁內存,同時也兼容普通的內存申請。

無鎖環形隊列

dpdk 基於 Linux 內核的無鎖環形緩衝 kfifo 實現了自己的一套無鎖機制。支持單生產者入列/單消費者出列和多生產者入列/多消費者出列操作,在數據傳輸的時候,降低性能的同時還能保證數據的同步。

poll-mode網卡驅動

DPDK網卡驅動完全拋棄中斷模式,基於輪詢方式收包,避免了中斷開銷。

NUMA

dpdk 內存分配上通過 proc 提供的內存信息,使 CPU 核心儘量使用靠近其所在節點的內存,避免了跨 NUMA 節點遠程訪問內存的性能問題。

CPU 親和性

dpdk 利用 CPU 的親和性將一個線程或多個線程綁定到一個或多個 CPU 上,這樣在線程執行過程中,就不會被隨意調度,一方面減少了線程間的頻繁切換帶來的開銷,另一方面避免了 CPU 緩存的局部失效性,增加了 CPU 緩存的命中率。

多核調度框架

dpdk 基於多核架構,一般會有主從核之分,主核負責完成各個模塊的初始化,從核負責具體的業務處理。

除了上述之外,dpdk 還有很多的技術突破,可以用下面這張圖來概之。
在這裏插入圖片描述

dpdk 的應用

dpdk 作爲優秀的用戶空間高性能數據包加速套件,現在已經作爲一個“膠水”模塊被用在多個網絡數據處理方案中,用來提高性。如下是衆多的應用。
在這裏插入圖片描述

數據面(虛擬交換機):

OVS
Open vSwitch 是一個多核虛擬交換機平臺,支持標準的管理接口和開放可擴展的可編程接口,支持第三方的控制接入。
https://github.com/openvswitch/ovs

VPP
VPP 是 cisco 開源的一個高性能的包處理框架,提供了 交換/路由 功能,在虛擬化環境中,使它可以當做一個虛擬交換機來使用。在一個類 SDN 的處理框架中,它往往充當數據面的角色。經研究表明,VPP 性能要好於 ovs+dpdk 的組合,但它更適用於NFV,適合做特定功能的網絡模塊。
https://wiki.fd.io/view/VPP

Lagopus
Lagopus 是另一個多核虛擬交換的實現,功能和 OVS 差不多,支持多種網絡協議,如 Ethernet,VLAN,QinQ,MAC-in-MAC,MPLS 和 PBB,以及隧道協議,如 GRE,VxLan 和 GTP。
https://github.com/lagopus/lagopus/blob/master/QUICKSTART.md

Snabb
Snabb 是一個簡單且快速的數據包處理工具箱。
https://github.com/SnabbCo/snabbswitch/blob/master/README.md

數據面(虛擬路由器):

OPENCONTRAIL
一個集成了 SDN 控制器的虛擬路由器,現在多用在 OpenStack 中,結合 Neutron 爲 OpenStack 提供一站式的網絡支持。
http://www.opencontrail.org/

CloudRouter
一個分佈式的路由器。
https://cloudrouter.org/
用戶空間協議棧

mTCP
mTCP 是一個針對多核系統的高可擴展性的用戶空間 TCP/IP 協議棧。
https://github.com/eunyoung14/mtcp/blob/master/README

IwIP
IwIP 針對 RAM 平臺的精簡版的 TCP/IP 協議棧實現。
http://git.savannah.gnu.org/cgit/lwip.git/tree/README

Seastar
Seastar 是一個開源的,基於 C++ 11/14 feature,支持高併發和低延遲的異步編程高性能庫。
http://www.seastar-project.org/

f-stack
騰訊開源的用戶空間協議棧,移植於 FreeBSD協議棧,粘合了 POSIX API,上層應用(協程框架,Nginx,Redis),純 C 編寫,易上手。

https://github.com/f-stack/f-stack
總結

dpdk 繞過了 Linux 內核協議棧,加速數據的處理,用戶可以在用戶空間定製協議棧,滿足自己的應用需求,目前出現了很多基於 dpdk 的高性能網絡框架,OVS 和 VPP 是常用的數據面框架,mTCP 和 f-stack 是常用的用戶態協議棧。很多大公司都在使用 dpdk 來優化網絡性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章