1. 程式人生 > >Open vSwitch流表查詢分析

Open vSwitch流表查詢分析

流表查詢過程是Open vSwitch核心中的核心。在此之前,庾志輝寫過關於對Open vSwitch(下文簡稱OVS)原始碼分析的系列部落格(連結如下:http://blog.csdn.net/yuzhihui_no1/article/details/39504139),時間是2014年9月25日,sdnlab前幾個月時間也對這個OVS原始碼分析系列進行了轉載(連結如下:http://www.sdnlab.com/3206.html)。

文中的分析對於研究OVS的人來說有很大的幫助,減少了許多閱讀程式碼的彎路,在這裡對他表示感謝。有一點不足的是,由於庾志輝當時分析的應該是OVS2.0(或者2.1)的程式碼,之後OVS對其自身查表的過程進行了改進,因此當前OVS版本(2.4)中描述的查表演算法與庾志輝當時分析的流表查詢過程已經有了一些區別。為此,本文對新改進的OpenFlow流表查詢演算法進行分析,供大家參考、交流。在庾志輝部落格中已經提到的內容就不在此贅述,主要講一些區別(即OVS流表查詢改進的地方)以及個人的一些理解。

背景

在一個網路交換裝置中,報文的處理流程可簡化為以下三個步驟:協議解析,表項查詢,動作執行(包含轉發、對報文的修改等動作),如圖1所示。由於表項的數目可能很大,匹配的形式包括最長字首匹配、精確匹配、範圍匹配,設計高效的查表演算法一直是網路研究人員追求的目標。表項查詢設計涉及到兩個方面:表項資料結構的組織和查表演算法的執行。

圖1 報文處理流程

OVS是部署在伺服器內部,用於實現虛擬機器之間交換的OpenFlow軟體交換機。軟體交換機通常執行在通用處理器(CPU)之上,因此其查表時間相比於用ASIC、TCAM、NP等硬體實現更慢。與傳統的路由器、交換機不同,OpenFlow的匹配域包含了L2-L4等匹配域。由於匹配域增多,為了防止表項產生組合爆炸問題,OpenFlow規範中指出,其轉發過程採用多級流水線查表設計。這樣一來,OVS高效查表的難度和挑戰進一步加大,其查表設計就顯得尤為重要,直接影響軟體轉發的效能。

本文將從表項查詢的兩個方面,表項資料結構的組織(Megaflow Cache+Microflow Cache)和查表演算法(元組空間搜尋),對OVS的流表查詢過程進行詳細分析。

OpenFlow流Cache的設計改進過程

一直以來,流Cache是提高查表效能的有效手段,已經被廣泛應用於報文查表加速。它將資料平面的轉發路徑分為快速路徑(即流Cache)和慢速路徑,利用流量區域性特性,使得大部分報文命中快速路徑中的表項,從而提高轉發效能。OVS也採用了流Cache設計思路。

OpenFlow流Cache的組織架構改進經歷了三個階段。

在早期OVS的版本中,為緩解多級流表查錶慢的問題,OVS在核心態採用Microflow Cache方法。Microflow Cache是基於Hash的精確匹配查表(O(1)),表項快取了多級查表的結果,維護的是每條連結粒度的狀態。Microflow Cache減少了報文進使用者態查多級表的次數。一條流的首報文進入使用者態查表後,後續的報文都會命中核心中的Microflow Cache,加快了查錶速度。但是對於大量短流的網路環境來說,Microflow Cache命中率很低,導致大部分報文仍然需要到使用者態進行多級流表查詢,因此轉發效能提升有限。

而後,為了解決Mircoflow Cache存在的問題,OVS採用Mircoflow Cache代替了Megaflow Cache。與Mircoflow Cache的精確Hash查表不同,Megaflow Cache支援帶通配的查表,所以可減少報文至使用者空間查表的次數。庾志輝的部落格中當時分析的就是關於megaflow的資料結構和查表流程,相關內容不在此贅述,請看上文中的連結。但是,由於OVS採用元組空間搜尋(下文介紹)實現Megaflow Cache的查詢,所以平均查表次數為元組表的數量的一半。假設元組空間搜尋的元組錶鏈為m,那麼平均查表開銷為O(m/2)。Mircoflow Cache和Megaflow Cache查表開銷對比為O(1)< O(m/2)。因此,Megaflow Cache相比於Mircoflow Cache,儘管減少了報文進使用者空間查表的次數,但是增加了報文在核心態查表的次數。

為此,OVS當前版本採用Megaflow Cache+Microflow Cache的流Cache組織形式,仍保留了Microflow Cache作為一級Cache,即報文進入後首先查這一級Cache。只不過這個Microflow Cache含義與原來的Microflow Cache不同。原來的Microflow Cache是一個實際存在的精確Hash表,但是最新版本中的Microflow Cache不是一個表,而是一個索引值,指向的是最近一次查Megaflow Cache表項。那麼報文的首次查表就不需要進行線性地鏈式搜尋,可直接對應到其中一張Megaflow的元組表。這三個階段的查表開銷如表1所示。

表1 查表開銷對比

流Cache的組織

查表開銷

備註

Mircoflow Cache

O(1)

 

Megaflow Cache

O(m/2)

m為元組表的數量

Mircoflow Cache& Megaflow Cache

P*O(1)+(1-P)*O(m/2)

P為命中一級表的概率

Microflow Cache和Megaflow Cache的組織和關係由於和查表演算法緊密關係,所以在下文分析完元組空間搜尋後給出。

附帶提兩點。1,在OVS的NEWS資料夾中記錄了每個版本更新的相關細節,包括流Cache的設計,所以讀者可在裡面搜尋到OVS功能演進過程的所有資訊。2,具體Megaflow的計算過程儘管不是本文討論的範圍,但的確非常精妙,有興趣的讀者可關注一下。

元組空間搜尋演算法

由於OpenFlow的匹配域擴充套件到了十二個欄位甚至更多的欄位,其協議解析後提取的查表關鍵字(即sw_flow_key)資料結構表示如圖2所示。

圖2 sw_flow_key資料結構

所以設計查詢演算法在效能、儲存方面更具挑戰。在防火牆、QoS等方面已經對多欄位查表進行了大量的研究,若將匹配域中的每一個欄位又被稱為一個維度,多欄位的軟體查表演算法大體上可以分為兩類:單維組合分類演算法和多維聯合分類演算法。單維組合查詢演算法的主要思想是:單獨地對資料包每個欄位進行匹配,並對每個欄位的匹配結果進行合併從而找到最終匹配的規則,其代表包括遞迴流分類(RFC)、位向量(BV)等。多維聯合分類查詢演算法的大致思想是不單獨地考慮每個欄位內部特點,而是簡單地把包頭的所有欄位看作一個維度,進行聯合查詢,其代表包括決策樹(Decision tree)、元組空間搜尋(TSS)等。

由於OVS選擇採用元組空間查詢(Tuple Space Search,TSS),因此這裡只重點介紹TSS演算法,感興趣的同學可百度其他演算法。TSS演算法的主要思想是,將所有規則按照各欄位字首長度的組合劃分成比規則數目小得多的元組集合,然後在這些元組裡進行雜湊查詢。舉個例子,有如下規則集,如表2所示包含三個匹配域和10條對應的規則。表中R1-R10為規則,F1、F2、F3為三個匹配欄位,每個欄位均為4bit。

表2 規則集

規則

F1

F2

F3

R1

0***

01**

100*

R2

01**

1***

010*

R3

1***

01**

110*

R4

00**

0***

100*

R5

*

0101

*

R6

1***

10**

101*

R7

00**

1***

000*

R8

*

1101

*

R9

*

1001

*

R10

10**

1***

010*

用[x,y,z]中的x、y、z分別表示F1、 F2、F3的字首長度。則10條規則表示如下。

表3 規則字首集

規則

字首組合[x,y,z]

R1

[1,2,3]

R2

[2,1,3]

R3

[1,2,3]

R4

[2,1,3]

R5

[0,4,0]

R6

[1,2,3]

R7

[2,1,3]

R8

[0,4,0]

R9

[0,4,0]

R10

[2,1,3]

由上表可知,規則可分為三類,R1、R3、R6∈[1,2,3],R5、R8、R9∈[0,4,0],R2、R4、R7、R10∈[2,1,3]。在不考慮規則優先順序的情況下,TSS的查詢表構造如圖3所示。

圖3 元組空間搜尋表

所以最多隻需要三次Hash查詢,即可找到對應表項。可以看到TSS的一個最大優點是,當所有規則的各欄位長度的組合相對較少時,TSS演算法是很高效的。如例子中的,10條規則只需要3次hash查詢即可。TSS的缺點是當所有規則的各欄位的組合很多時,最壞情況下的搜尋次數就變為n(n為規則的數量)。在上個例子中,假設所有規則的欄位組合都不一致,那麼TSS查表次數就為10,退化為最原始的順序查表。因此,TSS的演算法是否高效與轉發規則的特徵有直接的關係。

那麼為什麼OVS選擇TSS,而不選擇其他查詢演算法?論文[2]給出了以下三點解釋:

(1)在虛擬化資料中心環境下,流的新增刪除比較頻繁,TSS支援高效的、常數時間的表項更新;
(2)TSS支援任意匹配域的組合;
(3)TSS儲存空間隨著流的數量線性增長。

綜上原因,OVS選擇了TSS查表演算法,並對其進行了一些優化(優化的一些手段,例如優先順序排序、分段hash查詢等等,詳見論文和原始碼)。結合上面所提到的Microflow Cache和Megaflow Cache,給出目前OVS中核心態查表的流程,如圖4所示。

圖4 OVS核心查表流程

圖中紅色標記的Mask_cache_array即為Microflow Cache,是個地址,存放的是上一次匹配命中的Megaflow中某個元組表的索引值。其結構如下。

Shell
1 2 3 4 struct mask_cache_entry { u32 skb_hash ; / / SKB中五元組 hash後的值 u32 mask_index ; / /掩碼陣列 Mask _array的索引值 } ;

Mask_array是個指標陣列,陣列中每個元素存放的是掩碼,每個掩碼就代表一個元組表,。每條流的首報文都會遍歷這個陣列,相當於遍歷所有的元組表。每個元組表採用hash的方式,用鏈式解決Hash衝突。

Shell
1 2 3 4 5 struct mask_array { struct rcu_head rcu ; / / RCU控制 int count , max ; / /掩碼陣列的計數和最大值 struct sw_flow_mask __rcu * masks [ ] ; / /掩碼存放的陣列 } ;

以上就是目前OVS查表的分析,不足之處歡迎大家批評指正。

我們目前的工作

為進一步提高OVS轉發效率,我們目前正致力於FAST(Fpga Accelerated Sdn swiTc)開源專案。FAST採用可程式設計硬體(FPGA)對OVS的處理流程進行解除安裝加速,並利用FPGA可重構的特性擴充套件SDN交換機的功能,提高OpenFlow的轉發效能,推進SDN在實際環境中的部署。

總結和心得

一、實踐是檢驗真理的唯一標準
OVS的論文中出現過這樣的表述“我們根據實際部署後發現xxx這個更好”,說明對於演算法或者優化機制的選擇,有些時候是沒有理論依據的,而是根據在實際測試的結果作出的。這點從上面採用元組空間搜尋演算法的理由也可以看出。換句話說,如果不是在虛擬化資料中心的應用場景中,OVS是否還採用這樣的演算法和優化查表機制,就該值得商榷了。
二、溫故而知新
看大牛的論文時常覺得寫得晦澀難懂,一點也不易讀。但通常情況下是自己的姿勢水平不夠,相關的背景知識瞭解太少,基礎不夠,所以還要繼續學習。

參考文章
文中的分析主要參考來源於兩篇論文以及OVS2.4原始碼,如下:
[1] N. Shelly, E. Jackson, T. Koponen, N. McKeown, and J. Rajahalme. Flow Caching for High Entropy Packet Fields. In Proc. of HotSDN, 2014.

[2] Pfaff B, Pettit J, Koponen T, et al. The design and implementation of Open vSwitch[C]//12th USENIX Symposium on Networked Systems Design and Implementation. 2015.(NSDI 2015 Best Paper Award)

[3] Open vSwitch version 2.4. http://openvswitch.org/releases/openvswitch-2.4.0.tar.gz

作者簡介:
毛健彪:國防科技大學計算機學院網路與資訊保安研究所在讀博士生,從事軟體定義網路、資料中心網路等方面等研究。作者所在的課題組目前正在進行基於FPGA的SDN硬體交換機開源專案FAST的開發與推廣,特別感謝國防科技大學計算機學院網路所徐東來工程師在OVS程式碼分析過程中的幫助和指導。