昨天提到說明了
DHT便是將傳統的Hash Bucket變成一個個實體的Node
而Consistent Hashing是將Key與Node都一起Hash到同一個Hash Space,並將Data存到最近的Node裡面。
舉例:
以上就是 Consistent Hashing 的精神
但是目前這樣的做法有一個小問題,那就是對於[N3,1]之間的Data應該存在哪呢?
一種很直觀的方法就是將[0,1]區間變成一個 環狀!
而 CHORD 演算法就是基於這樣的一個環狀Hash Space設計自己的Routing方法。
CHORD是一個由MIT在2001年發表的一種DHT演算法。
作為一個Library,提供DHT給上層的 authentication、caching、replication、naming 等應用。
而CHORD的興起在於他非常簡單就可以實作。
開源網址在這裡: https://github.com/sit/dht/
裡面還包含了很多其餘相關的open source project,例如Merkle Tree
基於 Consistent Hashing 的想法,
如下圖所示,Keys與Nodes都會在同一個環上,我們將Data存入順時鐘方向最接近的Node上面。
幾個重點
每一個Node只會記錄兩個Neighbors
當一個Client連上某個Node希望找尋某個Data時,
若是該Node沒有該Data,便將請求傳遞給Successor。
舉例:
上面的m=7,就是假設Hash出來的ID為一個7bits的ID
一般採用SHA-1會是 160its
此種方法的缺點也很直觀,就是Worst Case會繞整個環一圈
因此時間複雜度會是O(N)
有沒有方法可以改善呢?
我們改成每一個Node可以記錄m個Neighbors,形成一個Finger Table來做Lookup,
定義:Finger i 指向 n+2^i
i=0~m-1 共m個點,
而n是目前的Node
如下圖舉例:
對於Node n12來說,其Finger Table定義如下m=7, n=12
Finger i | ID | 該ID對應到的Node |
---|---|---|
i=0 | 12+2^0=13 | N32 |
i=1 | 12+2^1=14 | N32 |
i=2 | 12+2^2=16 | N32 |
i=3 | 12+2^3=20 | N32 |
i=4 | 12+2^4=28 | N32 |
i=5 | 12+2^5=44 | N60 |
i=6 | 12+2^6=76 | N80 |
當Node記錄了上面的Finger Table,在搜尋目標Data時,就可以將原本的O(N)降為O(lgN)。
如下圖
這樣的Routing法可以將複雜度降到O(lgN)
為什麼呢?以下粗淺不專業的類比一下
從ID用m-bit表示
與Finger Table記錄的m個Node是每次增加2^i
你可以發現他每次都會嘗試找最接近的,而且是以2的次方在接近
就變成與二分搜的概念一樣
當然也就是O(lgN)
這個幾乎也是所有DHT演算法降時間複雜度的手段
以上就是DHT CHORD的Lookup介紹,明天會來介紹CHORD如何處理Data Partitioning與DHT的另外一個難題,也就是新增與刪除一個Node,如何重新分配那O(K/N)的Node。
Reference: