寫在前面
這算是看的第一篇完整的論文,對算法的地方整理了筆記和做了理解。如有錯誤之處,請指正。
其中有很多不足,比如目前還缺乏對數據層規則放置問題及其他相關研究這一點的整體理解。路漫漫其修遠兮。
回顧摘要
TCAM用來存儲(cache)規則(rule)的,數據包(packet)可以通過TCAM快速查找到高優先級的規則。
具體TCAM如何工作?基於TCAM的 Packet classification
TCAM的優勢衆所周知,但是這裏有幾點問題,也是文章的解決思路:
- TCAM容量限制:兩種switch,①TCAM(存儲popluar rule)容量大,快速更新;②sofeware switch(存儲cache miss)快速匹配。→怎樣區分popular和miss規則,需要規則放置→涉及規則依賴問題
- TCAM不能快速更新規則:怎樣規則替換→
引出規則依賴問題
CacheFlow模型
- 核心CacheMaster:控制層面。提供openflow接口,
- 數據層面:SW,TCAM
rule-dependency analysis
- R4、R5直接依賴,R5、R6直接依賴,則R4、R6間接依賴。
- 子→父
- 當一個規則cache到TCAM中,與之依賴的規則也應該存入TCAM→導致連鎖反應
- eg:若只有R5、R6。根據優先級,R6存入則R5必須存入,否則packet hit錯誤;但R5存入則R6不必存入。
- (補充)注意間接依賴的規則之間可能具有直接依賴也可能沒有(如①有依賴:R1和R3。可以添加一條箭頭R1→R3;②沒有依賴:R4和R6)
三個算法:
Constructing the Dependency DAG(構建依賴圖)
僞代碼:
// Add dependency edges
1 func addParents(R:Rule, P:Parents) begin
2 deps = (∅);
// p.o : priority order
3 packets = R.match; //①
4 for each Rj in P in descending p.o: do
5 if (packets ∩ Rj.match) != ∅ then
6 deps = deps ∪ {(R,Rj)}; //②
7 reaches(R,Rj) = packets ∩ Rj; //③
8 packets = packets - Rj.match; //④
9 return deps;
10 for each R:Rule in Pol:Policy do
11 potentialParents = [Rj in Pol | Rj.p.o ≤ R.p.o];
12 addParentEdges(R, potentialParents);
- 規則→節點,直接依賴→邊
- (★)P:Parents來自於11行 potentialParents(很重要,在後面算法中有用到,這裏簡稱P),在這裏表示比R優先級小的所有節點(不是所有父類節點,範圍更大)。
- 從優先級最高開始(即R1)
- ①將待查節點R的match(通配符)打包到packet,依次發送到所有R的P中;
- ②deps確定R(子)到Rj(父)的直接依賴邊;
- ③reaches(R,Rj)收集邊上的依賴(重疊)match部分;
- ④packets = packets - Rj.match更新packet:即減去packet的已依賴部分,接着遍歷下個Rj(即將packet發送到下個Rj)。
- 時間複雜度 O(n2),在動態網絡中添加、刪除成本太高
分析:
eg1:以R1爲例,
R1(000)的P有:R2(00x)、R3(0xx)、R4、R5、R6、R0(xxx)【優先級遞減】
for1:
- ①packets=000
- ②deps=(R1,R2)
- ③reaches(R1,R2)=R1→R2,攜帶000
- ④新的packets=000-00x=∅ //接着依次遍歷,結束
eg2:以R4爲例,
R1(11x)的P有:R5(1x0)、R6(10x)、R0(xxx)
for1:
- ①packets=11x
- ②deps=(R4,R5)
- ③reaches(R4,R5)=R4→R5,110
- ④新的packets=11x(110、111)-1x0(100、110)=111
for2:
- ①for1中的packets=111
- ②deps=(R4,R5)∪(R4,R0)
- ③reaches(R4,R0)=R4→R0,111
- ④新的packets=111-xxx=∅ //結束
Incremental Insert(插入)
僞代碼:
func FindAffectedEdges(rule, newRule) begin
2 for each C in Children(rule) do //①C爲rule的子
3 if Priority(C) > priority(newRule) then //②以下待查節點C爲newrule的子
4 if reaches(C,rule) ∩ newRule.match !=∅ then
5 reaches(C, rule) -= newRule.match;
6 add (C, Node) to affEdges
7 else //③以下待查節點C爲newrule的父
8 if Pred(C) ∪ newRule.match != ∅ then //④?
9 add C to potentialParents;
10 FindAffectedEdges(C, newRule);
11 func processAffectedEdges(affEdges) begin
12 for each childList in groupByChild(affEdges)
do
13 deps = deps ∪ {(child, newRule)};
14 edgeList = sortByParent(childList);
15 reaches(child, newRule) =reaches(edgeList[0]);
16 func Insert(G=(V, E), newNode) begin
17 affEdges = { };
18 potentialParents = [R0];
19 FindAffectedEdges(R0, newNode);
20 ProcessAffectedEdges(affEdges);
21 addParents(newNode, potentialParents);
- 整體算法是遞歸操作(先序遍歷)。更新時對無關部分不做處理
- 從R0開始遍歷,且R0必須添加到P中
步驟:
1. 遞歸遍歷現有生成樹,找到需要更新的邊(節點)
2. 通過檢查match交集和優先權,需要更新的分爲兩種:
- 該待查節點C爲newrule的子 :更新舊邊,將(C,node)添加到affEdges
- 該節點C爲newrule的父:將C添加到P中
分析:具體算法細節還有疑問,待更新。
Incremental Delete(刪除某節點)
刪除算法算是最簡單的
僞代碼:
1 func Delete(G=(V, E), oldRule) begin
2 for each c in Children(oldRule) do
3 potentialParents = Parents(c) - {oldRule}; //②更新
4 for each p in Parents(oldRule) do
//Find if deletion adds an edge E(c, p)
5 if reaches(c, oldRule) ∩ p.match != ∅
then
6 add p to potentialParents //①創建
7 addParents(C, potentialParents)
8 Remove all edges involving oldRule //③刪除
- ①創建新的邊:對於待刪除節點oldrule的所有子節點C,根據條件(reaches(c, oldRule) ∩ p.match != ∅),會創建oldR的子→oldR的父,也可能不創建
- ②更新現有的邊:oldR的子→{oldR的子的父-oldR}
- ③刪除:刪除與oldR直接依賴的邊
CACHING ALGORITHMS
規則如何放置。rule caching問題涉及到規則的依賴和網絡的動態變化。
- 運營商重寫策略簡化
- 通過算法實現
文章研究後者
- weight:該rule預計能匹配的packet數量
- cost:該rule 被依賴的規則數量,本身及其所有孩子
- ratio:∆W/ ∆C
brute-force algorithm(蠻力算法):
從n箇中取出k個:C nk=n(n-1)…(n-k+1)=O(nk)
Dependent-Set:
Maximize
∑i=1nwici subject to
∑i=1nci ≤k
ci − cj ≥ 0 if Ri.is_descendant(Rj ) ∀i, j ∈ {1, … , n}
//ci 爲父,cj 爲子,若父在,子必須在
ci ∈ {0,1} ∀i ∈ {1, … , n}
- 是貪心算法,但增加 c
i − cj ≥ 0 的條件 - 時間複雜度O(nk)
- 缺點:導致高cost
Cover-Set:
將popluar rule規則(如R)存入TCAM,而將依賴於R的miss rule規則(根據優先級,即R的所有子)存入到software switch中。並將R
- 好處:降低R的cost
- 缺點:由於重定位,導致wight可能升高
Mixed-Set:
1 func Mixed_Set(rule_table) begin
2 create_heap();
3 for r ∈ rule_table do
4 heap.insert(r.dep_set);
5 heap.insert(r.cover_set);
6 total_cost = 0;
7 while total_cost < threshold do
// pick element with maximum ∆ ∆W C
8 max_rule = heap.get_max();
// delete both dep-set and cover-set
9 heap.delete(max_rule);
10 if max_rule is dep_set then
11 for r1 ∈ dep_set(max_node) do
12 heap_delete(r1);
13 heap_update_ancestors(r1);
14 if max_rule is cover_set then
15 for r1 ∈ cover_set(max_rule) do
16 heap_update_ancestors(r1);
17 Add_Cache(max_rule.mixed_set);
Updating the TCAM Incrementally
cache-replacement strategies
更新緩存:時間變化→包流量分佈變化→規則緩存算法改變→更新TCAN策略
問題:
- 兩種規則之間的轉化需要過渡時間
- The nuclear option從頭刪除和插入,是非線性的
僞代碼:
1 func TCAM_Update(old_cache, new_cache)
begin
2 for mixed_set ∈ (old_cache − new_cache) do //①
3 for each rule in mixed_set do
4 if rule is normal then
5 rule.normal_ref−−;
6 if rule.normal_ref==0 then
7 delete_normal(rule)
8 else
9 rule.star_ref−−;
10 if rule.star_ref==0 then
11 delete_star(rule)
12 for mixed_set ∈ (new_cache − old_cache) do //②
13 for each rule in mixed_set do
14 if rule is normal then
15 if rule.normal_ref==0 then
16 install_normal(rule)
17 rule.normal_ref++;
18 else
19 if rule.star_ref==0 then
20 install_star(rule)
21 rule.star_ref++;
// Simply retain in TCAM, mixed_set ∈ new_cache ∩ old_cache. //③
- ①we first decompose/remove the old
mixed-sets (that are not cached anymore) from the TCAM
(lines 2-11) - ②compose with the new mixed sets
(lines 12-21) - ③retaining the mixed-sets common to
both the versions of the cache - Reference counting