Chrod算法是P2P中的四大算法之中的一個,是有MIT(麻省理工學院)於2001年提出,其它三大算法各自是:算法
Chord的目的是提供一種能在P2P網絡高速定位資源的的算法,Cord並不關心資源是怎樣存儲的,僅僅是從算法層面研究資源的取得,所以Chord的API就簡單到僅僅有一個set、get。網絡
Chord是一個算法,也是一個協議。做爲一個算法,Chord可以從數學的角度嚴格證實其正確性和收斂性;做爲一個協議,Chord具體定義了每個環節的消息類型。固然,Chord之因此受追捧,另外一個主要緣由就是Chord足夠簡單,3000行的代碼就足以實現一個完整的Chord。分佈式
Chord還可以被做爲一個一致性哈希、分佈式哈希(DHT)的實現。函數
覆蓋網絡是指這樣一種網絡:構建在其它網絡之上、網絡節點之間經過虛擬或邏輯鏈接在一塊兒,比方雲計算、分佈式系統都是覆蓋網絡,因爲其都構建於TCP/IP之上,且節點之間有聯繫。Chord也是構建於覆蓋網絡。性能
非結構化的P2P網絡是指網絡節點之間不存在組織關係,節點之間全然是對等的,比方第一代P2P網絡Napster,這類網絡結構清晰、簡單,但查找沒有多大的優化餘地,經常採用全局或分區泛洪查找,查找時間長、且結果難以保證(有可能在找到前就超時)。優化
結構化的P2P網絡與非結構化剛好相反,咱們以爲網絡在邏輯上存在一我的爲設計的結構,比方Chord假定網絡是一個環,Kadelima則假定爲一顆二叉樹,所有的節點均爲樹的葉子節點。有了這些邏輯結構,就給咱們資源查找引入了不少其它的算法和思路。雲計算
DHT的主要想法是把網絡上資源的存取像Hashtable同樣,可以簡單而高速地進行put、get,該思想的誕生主要是受第一代P2P(Napster)網絡的影響。與一致性哈希相比,DHT更強調的是資源的存取,而不管資源是不是一致性的。與一致性哈希一樣的是,DHT也僅僅是一個概念,詳細細節留給各實現。spa
當前這些P2P實現可以被做爲DHT的詳細實現,再次再列舉一些有表明性的實現:設計
Chord經過把Node和Key映射到一樣的空間而保證一致性哈希,爲了保證哈希的非反覆性,Chord選擇SHA-1做爲哈希函數,SHA-1會產生一個2160的空間,每項爲一個16字節(160bit)的大整數。咱們可以以爲這些整數首尾相連造成一個環,稱之爲Chord環。整數在Chord環上按大小順時針排列,Node(機器的IP地址和Port)與Key(資源標識)都被哈希到Chord環上,這樣咱們就假定了整個P2P網絡的狀態爲一個虛擬的環,所以咱們說Chord是結構化的P2P網絡。ip
如下有幾個定義:
如圖:
紅色點爲Node,藍色爲標誌符。上面僅僅是部分節點和標誌符,以節點N1爲例說明其Finger表中的successor:
No | ith successor | Successor |
1 | N1+20 | N18 |
2 | N1+21 | N18 |
3 | N1+22 | N18 |
4 | N1+23 | N18 |
5 | N1+24 | N18 |
6 | N1+25 | N45 |
7 | N1+26 | N1 |
8 | N1+27 | N1 |
把Node和Key都映射到一個值域感受是把狗和貓放在一塊兒衡量,儘管有點怪,但這樣可以保證一致性哈希,詳細可以參考前文。
很是顯然,分佈在Chord環上的Node數遠遠小於標誌符數(2160是一個沒法衡量的天文數字),這樣Chord環上的Node就會很是稀疏地分佈在Chord環上,理論上應該是隨機分佈,但如前面一致性哈希的討論,假設節點數量很少,分佈確定是不均勻的,可以考慮添加虛擬節點來添加其平衡性,假設在節點較多(比方大型的P2P網絡有上百萬的機器)就沒必要引入虛擬節點。
很是顯然,不論什麼查找僅僅要沿Chord環一圈結果確定可以找到,這種時間複雜度是O(N),N爲網絡節點數,但對一個上百萬節點,且節點經常增長、退出的P2P網絡來講,O(N)是不可忍受的,所以Chord提出瞭如下非線性查找的算法:
從直覺上來講,上次查找過程應該是指數收斂的,類似二分法的查找,收斂速度應該是很是快的;反過來,查找時間或路由複雜度應該是對數即的,在如下咱們會證實這一點。
下圖代表了節點N1查找節點N53的過程,仍是很快的:
對一個算法而言,收斂性是相當重要的,假設沒有收斂性作保證,在程序上化再多的心思也是徒勞。在證實以前,咱們再強調3點:
這裏要區分是Key的successor仍是節點n的successor,同一時候要注意近期匹配原則。
假如節點n的Finger表中的第i個successor與Key的距離近期,則知足:Key處在第i項與第i+1項中間
記第i項爲J,第i+1項爲P
而:
J = n + 2i-1
P = n + 2i
節點n與Key的距離應該處在n與J和P的中間,即 J-n<n - hash(Key)<P - n
(1) 2i-1<n - hash(Key)<2i
(2) 而J與Key的距離最大爲J與P的距離 J-hash(Key) <P - J = 2i-1
也就是說J與Key的距離,小於n與Key的距離,並且該距離小於n與Key距離的一半,這樣咱們保證每次迭代,與Key的距離都會收斂,並且至少按2的指數收斂,也就是折半查找。
至此,咱們理論證實了Chord的收斂性。
事實上Chord算法可以全然轉換爲一個數學問題:
在Chord環上隨意標記個點做爲Node集合,隨意指定Node T,從隨意的Node N開始依據Chord查找算法都能找到節點T。
爲何能這麼轉換呢?因爲僅僅要找到了Key的直接前繼,也就算找到了Key,所有問題轉化爲一個在Chord環上經過Node找Node的問題。這樣,這個題就當即變的很是奇妙,假如咱們把查找的步驟記錄爲路徑,又轉化爲隨意2個節點之間存在一條最短路徑,而Chord算法事實上就是構造了這樣一條最短路徑,那這種路徑會不會不存在呢?不會的,因爲Chord自己是一個環,最差狀況可以經過線性查找保證其收斂性。
從最短路徑的角度來看,Chord僅僅是對已存在線性路徑的改進,依據這個思路,咱們全然可以設計出其它的最短路徑算法。從算法原本來看,保證算法收斂或正確性的前提是每個Node要正確地維護其後繼節點,但在一個大型的P2P網絡中,會有節點的頻繁增長、退出,假設沒有額外的工做,很是難保證每個節點有正確的後繼。
Chord冗餘性:
所謂冗餘性是指Chord的Finger表中存在無用項,那些處在Node N和其successor之間的項均無心義,因爲這些項所表明的successor不存在。比方在N1的Finger表中的第1~5項均不存在,故都指向了N18,至少第1~4項爲冗餘信息。
通常說來,假如Chord環的大小爲2m,節點數爲2n,假如節點平均分佈在Chord環上,則任一節點N的Finger表中的第i項爲冗餘的條件爲:N+2i-1<N + 2m/2n =>2i-1<2m-n =>i <m-n+1,即當i <m-n+1時纔有冗餘。
冗餘度爲:(m-n+1)/m=1-(n-1)/m,通常說來m >>n,因此Chord會存在很是多的冗餘信息。假如,網絡上有1024個節點,即n=10,則冗餘度爲:1-(10-1)/160≈94%。因此很是多論文都指出這一點,並以爲會形成冗餘查詢,減小性能。事實上否則,因爲這些冗餘信息是分佈在多個Node的Finger表,假設採取適當的路由算法,對路由計算不會有不論什麼影響。
至此,咱們已經完整地討論了Chord算法及其核心思想,接下來要討論的是Chord的詳細實施。