Kademlia筆記


Kademlia協議(模型)是被電驢,BitTorrent所采用了的,基於異或距離算法的分布式散列表(DHT), 它實現了一個去中心化的信息儲存與查詢系統。

Kademlia將網絡設計為一個具有160層的二叉樹,樹最末端的每個葉子便是一個節點,節點在樹中的位置由同樣是160bit的節點ID決定。
每個bit的兩種可能值(0或1), 決定了節點在樹中屬於左面還是右面的子樹,160層下來,每個節點ID便都有了一個確定的位置。

Kademlia使用獨特的異或距離算法來計算節點間的距離,異或是一種簡單的數學計算,它有很多獨特的性質,這些性質在之后會為我們帶來方便:

自己與自己的距離為0:
x ^ x = 0
不同的節點間必有距離:
x ^ y > 0
交換律,x到y的距離等於y到x的距離:
x ^ y = y ^ x
從a經b繞到c, 要比直接從a到c距離長:
a ^b + b ^ c >= a ^ c
下面兩個是資料上提到的,似乎很重要,但我不大理解他們的含義:
a + b >= a ^ b
(a ^ b) ^ (b ^ c) = a ^ c

在Kademlia中,異或(距離)算法具有單向性(或者說一一對應關系),即給定一個節點和一個距離,必定存在唯一一個相對應節點。包括距離算法在內的,Kademlia中大部分的概念,都既有算術上的意義,又可以在節點樹上表現實際意義。
事實上,節點間距離反映的就是節點ID中比特的差異情況,而且越靠前的比特權值越大。或者說是反映節點在樹中相隔了多少個分支,需要向上多少個樹節點才能找到共同的祖先節點。

Kademlia中使用了名為K-桶的概念來儲存其他(臨近)節點的狀態信息,這里的狀態信息主要指的就是節點ID, IP, 和端口。
對於160bit的節點ID, 就有160個K-桶,對於每一個K-桶i, 它會儲存與自己距離在區間 [2^i, 2^(i+1)) 范圍內的節點的信息,每個K-桶中儲存有k個其他節點的信息,在BitTorrent的實現中,k的取值為8.

下表反映了每個K-桶所儲存的信息

K-桶 儲存的距離區間 儲存的距離范圍 儲存比率
0 [20, 21) 1 100%
1 [21, 22) 2-3 100%
2 [22, 23) 4-7 100%
3 [23, 24) 8-15 100%
4 [24, 25) 16-31 75%
5 [25, 26) 32-63 57%
10 [210, 211) 1024-2047 13%
i [2i, 2i+1) / 0.75i-3

放在節點樹上,即每個節點都更傾向於儲存與自己距離近的節點的信息,形成 儲存的離自己近的節點多, 儲存離自己遠的節點少 的局面。
從上表可以看出,在1-15這個范圍內的節點,只要發現,就會被100%地儲存下來,而離自己距離在1000左右的節點,只會儲存13%.

對於一個節點而言,K-桶就代表着節點樹上那些未知的節點(其實除了自己都是未知的)構成的子樹,160個K桶分別是具有1到160層的子樹,由小至大。對於節點ID, 160個K-桶分別儲存着節點ID前0到159個bit和自己一致的節點。

K-桶中的條目(其他臨近節點的狀態信息)排序的,每當收到一個消息(如查詢)時,就要更新一次K桶。
首先計算自己與對方的距離,然后儲存到對應的K-桶中,但如果K-桶已滿(前面提到每個K-桶儲存有k=8個條目), 則會傾向放棄儲存,繼續保持舊的節點信息(如果還有效的話). 除了距離外,Kademlia更傾向於與在線時間長,穩定的節點建立聯系。
這是因為實踐證明,累積在線時間越長的節點越穩定,越傾向於繼續保持在線,即節點的失效概率和在線時長成反比。
這樣還可以在一定程度上抵御攻擊行為。因為當大量惡意的新節點涌入時,大家都會選擇繼續保持舊的節點信息,而不是接受新的。
除此之外,還需要定時檢查K-桶中的節點是否任然在線,及時刪去已失效節點。

Kademlia協議僅定義了四種操作:

  • PING: 探測一個節點是否在線
  • STORE: 令對方儲存一份數據
  • FIND NODE: 根據節點ID查找一個節點
  • FIND VALUE: 根據鍵查找一個值(數據)

當查找一個節點時,首先計算自己與目標節點的距離d, 然后將 log2d 向下取整,找到對應的K-桶,從這個K-桶中選取a個節點(在BitTorrent的實現中取值為3), 向它們發送查詢。
收到查詢的節點同樣計算距離后從自己的對應K-桶中選取a個節點返回給查詢者。查詢者不斷重復這個過程,知道找到目標節點,或無法再找到更近的結果。
很多資料將這個過程描述成是遞歸的,但我覺得這里認為它是迭代的更為恰當。

因為每個節點都更傾向於儲存距自己近的節點的信息,而整個網絡又是一個二叉樹,因此每次查詢都會至少取得距離減半的結果,對於有N個節點的網絡,至多只需要 log2N 次查詢。

當進行 FIND VALUE 操作時,查詢操作是類型的,每份數據都有一個同樣是160bit的鍵,沒分數據都傾向於儲存在與鍵值距離較近的節點上。
當上傳者上傳一份數據時,上傳者首先定位幾個較為接近鍵值的節點,用STORE操作要求他們儲存這份數據。
儲存有數據的節點,每當發現比自己與鍵值距離更為接近的節點時,便將數據復制一份到這個節點上。

當一個新節點欲加入網絡時,只需找到一個已在網絡中的節點,借助它對自己的節點ID進行一次常規查詢即可,這樣便完成了對自己信息的廣播,讓距自己較近的節點獲知自己的存在。而離開網絡不必執行任何操作,一段時間后,你的信息會自動地從其他節點被刪除。

Kademlia的精妙之處在於它選擇了異或運算作為計算距離的依據,異或運算不僅具有算術的意義,在二叉樹式的網絡模型中,同樣具有實際意義,同時任何情況下都在強調距離的概念,讓節點間通過距離來聚合起來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM