怎麼提高網路應用效能?讓DPDK GRO和GSO來幫你!

李雪薇發表於2018-07-31

  目前,有大量的網路應用在處理資料包的時候只需要處理資料包頭,而不會運算元據負載部分,例如防火牆、TCP/IP協議棧和軟體交換機。對這類網路應用而言, 包頭處理產生的開銷(稱為“per-packet overhead”)佔了整體開銷的大部分。因此,如何減少包頭處理開銷是最佳化這類應用效能的關鍵。

   減少包頭處理開銷最直接的方法:減少資料包數量

  如何減少包數量?

  ●增大Maximum Transmission Unit (MTU)。在資料量一定的情況下,使用大MTU的資料包可攜帶更多資料,從而減少了包的總量。但MTU值依賴於物理鏈路,我們無法保證資料包經過的所有鏈路均使用大MTU。

  ●利用網路卡特性:Large Receive Offload (LRO),UDP Fragmentation Offload (UFO)和TCP Segmentation Offload (TSO)。如圖1所示,LRO將從物理鏈路收到的TCP包(如1500B)合併為長度更長的TCP包(如64KB);UFO和TSO將上層應用傳送的長資料負載的UDP和TCP包(如64KB)拆分成長度更短的資料包(如1500B),以滿足物理鏈路的MTU限制。透過在網路卡上進行包合併和拆分,在不需要任何CPU開銷的情況下,上層應用就可以處理數量大大減少的大包。然而,LRO、TSO和UFO通常只能處理TCP和UDP包,而且並非所有的網路卡都支援這些特性。

  ●軟體包合併 (Generic Receive Offload,GRO)和包拆分 (Generic Segmentation Offload,GSO)。與前兩種方法相比,GRO和GSO有兩個優點:第一,不依賴於物理鏈路和網路卡;第二,能夠支援更多的協議型別,如VxLAN和GRE。

  圖1. LRO、UFO和TSO工作原理

  為了幫助基於DPDK的應用程式(如Open vSwitch)減少包頭處理開銷,DPDK分別於17.08和17.11支援了GRO和GSO。如圖2所示, GRO和GSO是DPDK中的兩個使用者庫,應用程式直接呼叫它們進行包合併和分片。

  圖2. DPDK GRO和DPDK GSO

   1、GRO庫和GSO庫結構

  圖3描繪了GRO庫和GSO庫的結構。根據資料包型別,GRO庫定義了不同的GRO型別。每一種GRO型別負責合併一種型別的資料包,如TCP/IPv4 GRO處理TCP/IPv4資料包。同樣的,GSO庫也定義了不同的GSO型別。GRO庫和GSO庫分別根據MBUF的packet_type域和ol_flags域將輸入的資料包交給對應的GRO和GSO型別處理。

  圖3. GRO庫和GSO庫的框架

   2、如何使用GRO庫和GSO庫?

  使用GRO和GSO庫十分簡單。如圖4所示,只需要呼叫一個函式便可以對包進行合併和分片。

  圖4. 程式碼示例

  為了支援不同的使用者場景,GRO庫提供了兩組API:輕量模式API和重量模式API,如圖5所示。輕量模式API應用於需要快速合併少量資料包的場景,而重量模式API則用於需要細粒度地控制合包並需要合併大量資料包的場景。

  圖5. 輕量模式API和重量模式API

   3、DPDK GRO的合包演算法

   演算法挑戰

  ●在高速的網路環境下,高開銷的合包演算法很可能會導致網路卡丟包。

  ●包亂序(“Packet Reordering”)增加了合包難度。例如Linux GRO無法合併亂序的資料包。

  這就要求DPDK GRO的合包演算法:

  足夠輕量以適應高速的網路環境

  能夠合併亂序包

   基於Key的合包演算法

  為解決上述兩點挑戰,DPDK GRO採用基於Key的合包演算法,其流程如圖6所示。對新到的資料包,首先按照流(“flow”)對其進行分類,再在其所在的流中尋找相鄰的資料包(“neighbor”)進行合併。若無法找到匹配的流,就插入一條新流並將資料包儲存到新流中。若無法找到鄰居,則將資料包儲存到對應的流中。

  基於Key的合包演算法有兩個特點。首先,透過流分類來加速資料包的合併是十分輕量的一種做法;其次,儲存無法合併的資料包(如亂序包)使得之後對其進行合併成為可能,故減輕了包亂序對合包帶來的影響。

  圖6. 基於Key的合包演算法流程

   4、DPDK GSO的分片策略

   分片流程

  如圖7所示,將一個資料包分片有3個步驟。首先,將包的資料負載分成許多長度更小的部分;其次,為每一個資料負載部分新增包頭(新形成的資料包稱為GSO Segment);最後,為每個GSO segment更新包頭(如TCP Sequence Number)。

  圖7. GSO分片流程

   GSO Segment的結構

  生成一個GSO Segment的最簡單方法就是複製包頭和資料負載部分。但頻繁的資料複製會降低GSO效能,因此,DPDK GSO採用了一種基於零複製的資料結構——Two-part MBUF——來組織GSO Segment。如圖8所示,一個Two-part MBUF由一個Direct MBUF和多個Indirect MBUF組成。Direct MBUF用來儲存包頭,Indirect MBUF則類似於指標,指向資料負載部分。利用Two-part MBUF,生成一個GSO Segment僅需複製長度較短的包頭,而不需要複製較長的資料負載部分。

  圖8. Two-part MBUF的結構

   GRO庫和GSO庫的狀態

  目前,GRO庫還處於一個初期階段,僅對使用最廣泛的TCP/IPv4資料包提供了合包支援。GSO庫則支援更豐富的包型別,包括TCP/IPv4、VxLAN和GRE。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31509936/viewspace-2168802/,如需轉載,請註明出處,否則將追究法律責任。

相關文章