在ovs交換機中,報文的處理流程能夠劃分爲一下三個步驟:協議解析,表項查找和動做執行,其中最耗時的步驟在於表項查找,每每一個流表中有數目巨大的表項,如何根據數據報文的信息快速的查找到對應的流表項是ovs交換機的一個重要的功能。html
在openflow協議中,支持多級流表的形式,能夠類比於將一個複雜的功能進行打散,分解成過個小的功能,實現一個流水線的功能,具體見下圖:算法
上圖中能夠看到,一個數據報文進入後,會通過多個流表,每一個流表負責特定的功能,好比上圖中table 1中的流表項只會與數據報文中L2層的信息進行匹配,多個流表的處理使得整個數據報文的查詢造成一種流水線的處理方式。segmentfault
首先須要明確的是,ovs中的多級流表存放在用戶空間,內核態存放的是流表的緩存,數據報文進入ovs的時候,首先會查詢內核態的緩存信息,若是命中則直接執行相應的動做,不然經過netlink的方式發送到用戶空間,用戶空間查找多級流表,若是用戶態命中則將對應的信息丟給內核態進行緩存,不然查詢不到,用戶態還要繼續將報文的信息丟給控制器,由控制器下發對應的規則,有關ovs和控制器之間的關係能夠參見個人上一個博客。緩存
ovs中關於流表的查詢經歷了三個過程:ide
microflow cache的思想十分簡單,具體見下圖:性能
多級流表的查詢過程當中,會將報文與每一個流表的每一個流表項進行匹配,這個過程當中耗費的時間是很大的,microflow cache的想法就是將多級流表查詢以後的結果按照必定的表項格式直接緩存到內核態中,而後下次一樣的數據報文到達時,直接經過hash的方法在內核態中命中,第二次的時間複雜度爲$O(1)$,ui
microflow cache的缺點也很明顯:spa
雖然基於microflow cache的流表查詢方式,能讓數據報文第二次命中的時間複雜度達到$O(1)$,可是其真正的性能瓶頸在於用戶空間的查詢,如何減小數據報文進入用戶態,是一個很重要的問題。設計
爲了解決精確匹配的問題,減小數據報文進入用戶態,ovs採用了megaflow cache代替了microflow cache的匹配方式,megaflow cache是一種基於TTS(元組空間搜索算法)的實現方式,採用了模糊匹配取代microflow cache的精確匹配,經過增長在內核態中查詢的時間(從1次hash查找到k次,仍然是常數時間內,跟TTS算法中表的數量有關),減小數據報文進入用戶態的次數,具體會在TTS算法中解釋。htm
一種樸素的megaflow cache實現方式就是,將全部多級流表的級聯結果存放在內核態中,以下圖:
內核態中存放着一張全部流表級聯以後的大表,顯而易見,這種作法簡單粗暴,可是內存的開銷也是巨大的。
一種好的作法是,採用’Lazy‘的方式,以下圖所示,數據報文首先經過模糊匹配的方式檢索內核中的表,若是全部的表都沒法命中,則查詢用戶態,而後將用戶態的查詢出的全部表項合併成一條表項,再插入到內核態的表中。
須要注意的是,上圖中megaflow cache是一張表,在實際的ovs實現中,由於採用了TTS,因此megaflow cache是多張表造成的鏈表。
目前版本的ovs採用的是第三種查詢方式,也就是結合microflow cache和Megaflow Cache,其中microflow cache做爲一級cache,Megaflow Cache做爲二級cache,此時microflow cache中存放的再也不是多級流表返回的結果,而是上一次在Megaflow Cache中命中的索引。
數據報文到達時,首先經過對報文信息hash,查詢microflow cache中是否存放着對應的hash值,若是存在則查詢對應hash值所指向的索引,這個索引用來定位對應的Megaflow鏈表中的某一個元素表,而後再在這個元素表中進行查找。
總體的解釋起來可能有點拗口,本人也是第一次寫博客,對ovs瞭解的也不夠深刻,其中涉及到不少細節也不是很清楚,但願經過分享的形式同你們交流。
參考資料
[Pfaff B, Pettit J, Koponen T, et al. The Design and Implementation of Open vSwitch[C]//NSDI. 2015, 15: 117-130.](https://www.usenix.org/system...
Open vSwitch流表查找分析
The Design and Implementation of Open vSwitch 做者演講ppt
做者: yearsj
轉載請註明出處: https://segmentfault.com/a/11...