海量路由表能够使用HASH表存储吗-HASH查找和TRIE树查找
非常多人這樣說,也包括我。
Linux內(nèi)核早就把HASH路由表去掉了。如今就僅僅剩下TRIE了,只是我還是希望就這兩種數(shù)據(jù)結(jié)構(gòu)展開一些形而上的討論。
1.hash和trie/radix
hash和tire事實上是能夠統(tǒng)一在一起的。具有同樣hash值的多個項具有一個共同的特征,這個特征怎么提取呢?無疑這就是hash函數(shù)的工作。而trie樹(或者radix樹,管它呢)的一棵子樹也有共同的特征,這個特征怎么提取呢?無疑這就是該子樹根節(jié)點的父節(jié)點指示的某些bits在這棵子樹的每個節(jié)點都具有同樣的值。
?????? 實際上,trie樹就是hash的一種特殊形式,其hash函數(shù)為:取某些bits
那么。這么看來,子樹的全部節(jié)點都應(yīng)處在一個“沖突鏈表”里面了...trie樹的做法就是“再次hash”,hash函數(shù)隨之改變。變成取level.bits更低的某些bits了。如此看來。hash路由表解決海量路由項情況下沖突鏈表變長的方案就是再次hash了,hash函數(shù)變成什么呢?我們后面再談。
2.TCAM的hash
TCAM在非常多地方被用到,它用來依據(jù)內(nèi)容查索引,常被用于路由查詢。CPU Cache查詢等,以CPU Cache為例。輸入TCAM的內(nèi)容就是一個內(nèi)存地址,而輸出的結(jié)果是一個索引。cache匹配的過程就是取到索引指示的cache line,然后比較輸入內(nèi)容(地址)和該cache line指示的地址是否一致。一致就是命中。?????? 那么TCAM中最核心的過程就是依據(jù)地址得到索引的過程,一般的做法就是hash,由于硬連線實現(xiàn),hash函數(shù)絕對不能有太多的計算。因此一般的做法就是“取地址某些bits”,比方取4到7位一共4位,將一個32位(32位系統(tǒng),物理地址索引cache為例為例)的慢速物理內(nèi)存地址映射到4位高速cache索引。形成一個金字塔存儲結(jié)構(gòu)。32位到4位的映射,丟失了的28位會形成非常大可能性的沖突,而這個就是時間局部性和空間局部性來盡力彌補了,了解列維飛行的應(yīng)該知道局部性的偉大含義,它構(gòu)建了我們整個人類文明。
?????? 最簡單的hash函數(shù)就是取模,實際上也是“取某些bits”,它更加特殊,它是“取最低N bits"。
3.hash和trie樹的統(tǒng)一
trie樹實際上是從高位到低位逐步hash的過程構(gòu)建的,其hash函數(shù)就是”取某些bits“。4.查字典的樣例-查英文和查漢字
我們小學的時候查字典一般分為音序查法和部首查法,它就形象能體現(xiàn)hash和trie的不同。為了簡便,我以英文單詞查法和漢字部首查法為例。
?????? 英文單詞是嚴格一維度順序排列的,且僅有26個字母組成。因此它能夠依照trie樹的方式查詢,比方what。who,where,前兩個字符都是wh,因此說它們具有這么一個共同特征。假設(shè)將取這個共同特征作為hash函數(shù),那么在aaa。cc,sahidad。fwfwew,what,qwert,azsx,who。eee,ooo,where中查詢who,what。who,where將形成沖突鏈表,可是一步運算大大降低了匹配的數(shù)量,從11個減為3個,然后再進一步hash,依照字母順序可知at,wre。o這個順序,直接取第三個孩子節(jié)點。因此英語詞典的查詢方式非常簡便。就是一個不斷hash定位的過程。hash函數(shù)就是”取某些連續(xù)字符“。
?????? 我們再看看漢字部首查詢法。它是一個典型的計算型hash函數(shù)的不斷hash的過程。比方在楊。林,棵,馬,牛,豬,過。皮這幾個字中查”林“字,由于漢字不是一維結(jié)構(gòu)而是二維結(jié)構(gòu)。它的構(gòu)成是筆畫。不是排序的,因此”取某些字符“的方式全然失效(從哪個方向開始取?...怎么算一個字符?...),因此就須要又一次構(gòu)造hash函數(shù)了。長期的歷史形成的漢子具有某種象形的意義。通過觀察。我們發(fā)現(xiàn)”木“字旁是一個特征,這個計算過程,也就是hash函數(shù)運行過程是我們的大腦來完畢的。假設(shè)說”取某些字符“更加適用于硬件實現(xiàn),那么發(fā)現(xiàn)偏旁部首則更加適合軟件實現(xiàn),從中我們也能夠分析出中國人和西方人的思維之差別。繼續(xù)往下說。發(fā)現(xiàn)”木字旁“之后。楊。林,棵形成了沖突鏈表,但大大降低了匹配候選字的數(shù)量。不想遍歷的話。須要再次hash,新華字典設(shè)計了筆畫數(shù)這個再hash函數(shù),”林“字除了偏旁之外還剩下4筆畫。于是定位到了”林“。假設(shè)還沖突,那就須要遍歷了,由于商務(wù)印書館可能想不出什么hash函數(shù)了(我不知道這樣的漢字部首查字法是誰發(fā)明的,就當是出版社的杰作吧...)。
反過來看英文查法??偸悄軌蚪K于確定性定位,由于它的不斷hash的hash函數(shù)是”取連續(xù)字符“,加之單詞長度有限且一維排列順序遞進??偸悄軌虻阶詈笠粋€字符的。
?????? 看出差別了嗎?看出trie樹查詢和hash查詢的差別了嗎?
5.hash路由表和trie路由表
對于hash路由表查詢而言,最長前綴匹配邏輯并沒有包括在hash過程中,它來自于一種冒險行為,前提是對hash函數(shù)的足夠自信。hash路由表查找直接從32位前綴hash表開始。逐步回歸到0位前綴hash表,期望在這個過程中能高速得到第一個結(jié)果,這第一個匹配結(jié)果就是終于結(jié)果。?????? 對于trie路由表查詢而言,最長前綴匹配邏輯包括在不斷再hash的邏輯中。它匹配的是最后一個結(jié)果而不是第一個,由于”順序取某些bits“不斷hash的過程。最后匹配到的顯然是最精確的。這是和hash路由查詢的本質(zhì)差別。trie查詢沒有冒險行為,它不須要冒遍歷超長沖突鏈表之險,由于老老實實地運行順序取bits這個過程總能將查詢過程引到目的地。
6.海量路由項的情況
Linux之所以用了那么久hash路由表組織,是由于它足夠了。由于在大部分時間。路由表項數(shù)量是不多的。即便是遍歷也不會有太大的開銷,而hash的計算會大大降低遍歷的開銷,所謂的冒險最壞情況就是遍歷整個路由項,這不是為題??墒且坏┍闅v整個路由表的全部路由項真的成了一個大風險的時候?;蛘哒f即使遍歷一半也吃不消的時候,用hash就不明智了。
這和獅子追羚羊時的博弈相似。一個風險是一頓飯,一個風險是一條命,這是嚴格不正確稱的。所以總是看到羚羊勝利(還真不能把這個當零和游戲,由于獅子有時真的不在乎)。
?????? 如今的問題是,怎樣使用hash路由表并降低風險。我們先看一下Linux自己的hash函數(shù):
可見它將輸入的非0項散列得足夠開,可是hash的本質(zhì)就是大空間往小空間映射。沖突在所難免。
有人提出(比方我)在海量路由表項時將長沖突鏈表組織成trie樹的形式,可是這有意義嗎?假設(shè)是一個完整的trie路由表。最長32步(考慮壓縮和回溯)就能找到結(jié)果。假設(shè)採用hash+trie的方式,每一步的最壞結(jié)果都是32步,一共進行32步...這樣做沒有意義。
?????? 海量路由表項時,hash小空間是嚴格有范圍的。能夠覺得它是固定的。平均情況非常easy通過地址空間和hash空間求得,最壞情況則是全然遍歷。平均情況假設(shè)都不能接受,難道值得為最好情況去冒險嗎?因此,千萬別用hash表存儲海量路由表項。
?????? 可是。還沒完
7.局部性利用以及DoS
32位系統(tǒng),CPU Cache相比內(nèi)存而言非常小,怎么能夠帶來如此大的優(yōu)化?全部映射到同一個cache line的地址都是沖突的啊...這是由于CPU Cache利用了程序的時間/空間局部性,而對于路由而言。則沒有空間局部性。時間局部性能夠用于路由cache,然而用于路由表本身則有難度。路由表和CPU Cache的差別在于它是全然的。不存在被替換和老化的問題。因此能夠把好的hash函數(shù)用于單獨的路由cache,而路由表僅僅用于路由cache不命中的情況下去匹配。
?????? 理想情況分析完了,剩下的僅僅是悲哀了。
?????? 網(wǎng)絡(luò)訪問的時間局部性真的能夠利用嗎?盡管一個5元組的數(shù)據(jù)流通常會隨著時間持續(xù)經(jīng)過路由器,可是假設(shè)hash沖突的還有一個數(shù)據(jù)流也經(jīng)過的話,就會造成cache抖動,在CPU Cache看來。這個問題能夠通過控制task切換或者添加cache line唯一鍵值來解決,可是對于網(wǎng)絡(luò)訪問,你沒法阻止不論什么一個數(shù)據(jù)包的到來,僅僅要到來就要查詢路由表,就有可能導致cache抖動。更嚴重的。路由cache非常easy受到精心構(gòu)造的數(shù)據(jù)包的攻擊造成不可用,頻繁的替換或者無限的加長鏈表。平添了查詢開銷。
?????? 因此設(shè)計一個全然的轉(zhuǎn)發(fā)表而不是利用路由cache更加能提升轉(zhuǎn)發(fā)效率。
這又一次為我的DxR Pro結(jié)構(gòu)作了一個廣告。
轉(zhuǎn)載于:https://www.cnblogs.com/mfrbuaa/p/5248393.html
總結(jié)
以上是生活随笔為你收集整理的海量路由表能够使用HASH表存储吗-HASH查找和TRIE树查找的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对于干燥的B级绝缘发电机定子绕组而言,通
- 下一篇: ORA-28001: the passw