日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Chord算法

發(fā)布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Chord算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自:http://blog.csdn.net/wangxiaoqin00007/article/details/7374833

雖然網(wǎng)上搜索CHord,一搜一大堆,但大多講得不太清楚明白。今天發(fā)現(xiàn)一篇blog,圖文并茂,邏輯清楚且易懂,特意轉(zhuǎn)載收藏。

?

P2P的一個常見問題是如何高效的定位節(jié)點,也就是說,一個節(jié)點怎樣高效的知道在網(wǎng)絡(luò)中的哪個節(jié)點包含它所尋找的數(shù)據(jù),如下圖:

對此,有三種比較典型的來解決這個問題。

Napster:使用一個中心服務(wù)器接收所有的查詢,服務(wù)器告知去哪下載其所需要的數(shù)據(jù)。存在的問題是中心服務(wù)器單點失效導(dǎo)致整個網(wǎng)絡(luò)癱瘓。

Gnutella:使用消息洪泛(message flooding)來定位數(shù)據(jù)。一個消息被發(fā)到系統(tǒng)內(nèi)每一個節(jié)點,直到找到其需要的數(shù)據(jù)為止。當(dāng)然,使用生存時間(TTL)來限制網(wǎng)絡(luò)內(nèi)轉(zhuǎn)發(fā)消息的數(shù)量。存在的問題是消息數(shù)與節(jié)點數(shù)成線性關(guān)系,導(dǎo)致網(wǎng)絡(luò)負(fù)載較重。

SN型:現(xiàn)在大多數(shù)采用所謂超級節(jié)點(Super Node),SN保存網(wǎng)絡(luò)中節(jié)點的索引信息,這一點和中心服務(wù)器類型一樣,但是網(wǎng)內(nèi)有多個SN,其索引信息會在這些SN中進(jìn)行傳播,所以整個系統(tǒng)的崩潰幾率就會小很多。盡管如此,網(wǎng)絡(luò)還是有崩潰的可能。

現(xiàn)在的研究結(jié)果中,Chord、Pastry、CAN和Tapestry等常用于構(gòu)建結(jié)構(gòu)化P2P的分布式哈希表系統(tǒng)(Distributed Hash Table,DHT)。

DHT的主要思想是:首先,每條文件索引被表示成一個(K, V)對,K稱為關(guān)鍵字,可以是文件名(或文件的其他描述信息)的哈希值,V是實際存儲文件的節(jié)點的IP地址(或節(jié)點的其他描述信息)。所有的文件索引條目(即所有的(K, V)對)組成一張大的文件索引哈希表,只要輸入目標(biāo)文件的K值,就可以從這張表中查出所有存儲該文件的節(jié)點地址。然后,再將上面的大文件哈希表分割成很多局部小塊,按照特定的規(guī)則把這些小塊的局部哈希表分布到系統(tǒng)中的所有參與節(jié)點上,使得每個節(jié)點負(fù)責(zé)維護(hù)其中的一塊。這樣,節(jié)點查詢文件時,只要把查詢報文路由到相應(yīng)的節(jié)點即可(該節(jié)點維護(hù)的哈希表分塊中含有要查找的(K,V)對)。

這里介紹的Chord算法就是解決網(wǎng)絡(luò)內(nèi)節(jié)點定位問題的一種P2P協(xié)議。它通過多個節(jié)點跳轉(zhuǎn)找到我們所查找的資源:

我們先看看它是如何進(jìn)行的,隨后再總結(jié)其特點和操作特征,以及一些實現(xiàn)。

1.Chord里面的基本要素

節(jié)點ID:NID(node identifier),表示一個物理機(jī)器,m位的一個數(shù)字(m要足夠大以保證不同節(jié)點的NID相同的幾率小的可以忽略不計),由節(jié)點機(jī)器的IP地址通過哈希操作得到。

資源ID;KID(key identifiers),原為鍵ID,其實際表示一個資源(因為Key與一個資源value哈希綁定),故在本文中統(tǒng)稱資源ID(這樣比較直觀),m位的一個數(shù)字(m要足夠大以保證不同資源的KID相同的幾率小的可以忽略不計),由Key通過哈希操作得到。

常哈希函數(shù):較之一般哈希函數(shù),節(jié)點的加入和離開對整個系統(tǒng)影響最小,另外還有一些優(yōu)勢在此不贅述。在Chord中使用SHA-1來進(jìn)行常哈希計算。

Chord環(huán):Chord Ring,NID和KID被分配到一個大小為2^m的環(huán)上,用于資源分配(給某一個節(jié)點)和節(jié)點分布,以及資源定位(注:在這個環(huán)上的ID為0--2^m-1)。首先我們說資源分配,資源被分配到NID>=KID的節(jié)點上,這個節(jié)點成為k的后繼節(jié)點,是環(huán)上從k起順時針方向的第一個節(jié)點,記為successor(k)。而節(jié)點分布則順時針將節(jié)點N由大到小放在這個環(huán)上。例如下邊這幅圖:

這是一個m=6的環(huán),其中有10個節(jié)點,5個資源,K10的后繼節(jié)點為N14,也就是說K10被分配給了N14。

2.Chord資源定位(Key Location)

資源定位是Chord協(xié)議的核心功能,為了便于理解,我們先介紹一個簡單的資源定位方法,然后再介紹這個可伸縮的資源定位方法。

簡單方法:

考慮如下場景:節(jié)點n尋找KID為id的資源,此時節(jié)點n首先問詢是否在下一個節(jié)點上(find_successor),這要看資源k的KID是否在該節(jié)點NID和下一個節(jié)點的NID之間,若在則說明資源k被分配給了下一個節(jié)點,若不在則在下一個節(jié)點上發(fā)起同樣的查詢,問詢下下一個點是否有該資源。如此迭代下去,用偽代碼定義這個操作:

n.find_successor(id)?
?? if (id ? (n; successor])?
?????? return successor;?
?? else?
?????? // 將查詢沿著環(huán)進(jìn)行下去?
???? return successor.find_successor(id);

例如下圖:

節(jié)點N8尋找K54這個資源,N8.find_successor(K54)發(fā)現(xiàn)下一個節(jié)點N14不合符54? (8; 14],于是N14發(fā)起同樣的搜索,然后一跳一跳后直到節(jié)點N56滿足54? (51; 56],于是得知資源K54在N56這個節(jié)點上。

在一個有N個節(jié)點的環(huán)上,這樣的查找方法顯然在最壞的時候要查找N次才能得到所需資源的位置,查找次數(shù)與節(jié)點個數(shù)成線性關(guān)系。顯然,這樣的效率不給力,所以Chord使用了可伸縮資源定位的方式來提高效率。

可伸縮方法:

在每個節(jié)點N上都維護(hù)了最多有m項(m為ID的位數(shù))的路由表(稱為finger table),用來定位資源。這個表的第i項是該節(jié)點的后繼節(jié)位置,至少包含到2^(i-1)后的位置。還是延續(xù)上邊的例子:

節(jié)點N8的路由表中,左邊那一欄包含了N8+1到N8+32(2^5-1)的位置,右邊那一欄每個位置對應(yīng)的實際存在的節(jié)點。比如N8+1-N14,表示在N8后的第一個位置上的資源由N14來負(fù)責(zé)。這樣記錄有以下優(yōu)勢:

每個節(jié)點只包含全網(wǎng)中一小部分節(jié)點的信息。

每個節(jié)點對于臨近節(jié)點負(fù)責(zé)的位置知道的更多,比如N8節(jié)點對于N14負(fù)責(zé)的位置知道3處,而對N21負(fù)責(zé)的位置只知道1處。

路由表通常不包含直接找到后繼節(jié)點的信息,往往需要詢問其他節(jié)點來完成。

當(dāng)在某個節(jié)點上查找資源時,首先判斷其后繼節(jié)點是不是就持有該資源,若沒有則直接從該節(jié)點的路由表從最遠(yuǎn)處開始查找,看哪一項離持有資源的節(jié)點最近(發(fā)現(xiàn)后跳轉(zhuǎn)),若沒有則說明本節(jié)點自身就有要尋找的資源。如此迭代下去。

例如:節(jié)點N8尋找K54這個資源

首先,在N8上查找后繼節(jié)點為N14,發(fā)現(xiàn)K54并不符合54? (8; 14]的要求,那么直接在N8的路由表上查找符合這個要求的表項(由遠(yuǎn)及近查找),此時N8的路由表為:

我們發(fā)現(xiàn)路由表中最遠(yuǎn)的一項N8+32--N42滿足42? (8; 54],則說明N42這個點離持有K54這個資源的節(jié)點最近(因為N42在該路由表中離N8這個節(jié)點最遠(yuǎn)),那么此時跳到N42這個節(jié)點上繼續(xù)查找。N42的后繼節(jié)點為N48,不符合54? (42; 48]的要求,說明N48不持有資源54,此時,開始在N42的路由表上查找:

N42節(jié)點的路由表為:

我們由遠(yuǎn)及近開始查找,發(fā)現(xiàn)N42+8--N51滿足51? (42; 54],則說明N51這個點離持有K54這個資源的節(jié)點最近,那么此時跳到N51這個節(jié)點上繼續(xù)查找。N51節(jié)點的后繼節(jié)點為N56,符合54? (51; 56],此時定位完成,N56持有資源節(jié)點K54。

用偽代碼表示:

// 查詢節(jié)點n后繼節(jié)點。?
n.find_successor(id)?
if (id ? (n; successor])?
return successor;?
else n0 = closest_preceding_node(id);?
return n0.find successor(id);?
// search the local table for the highest?
// predecessor of id?
n.closest_preceding_node(id)??
for i = m downto 1?
if (finger[i] ? (n; id))?
return finger[i];?
return n;

經(jīng)證明,最多經(jīng)過O(log N)次查找就能找到一個資源。

3.Chord的節(jié)點加入

Chord通過在每個節(jié)點的后臺周期性的進(jìn)行stabilization詢問后繼節(jié)點的前序節(jié)點是不是自己來更新后繼節(jié)點以及路由表中的項。

有三個操作:?
join(n0) :n加入一個Chord環(huán),已知其中有一個節(jié)點n0.

Stabilize(): n查詢其后繼節(jié)點的前序節(jié)點P來決定P是否應(yīng)該是n的后續(xù)節(jié)點,也就是說當(dāng)p不是n本身時,說明p是新加入的,此時將n的后繼節(jié)點設(shè)置為p。

Notify(n0): n0通知n它的存在,若此時n沒有前序節(jié)點或,n0比n現(xiàn)有的前序節(jié)點更加靠近n,則n將其設(shè)置為前序節(jié)點。

Fix_fingers(): 修改路由表。

具體的,例如:

這是原先的結(jié)構(gòu):

現(xiàn)在N26節(jié)點要加入系統(tǒng),首先它指向其后繼N32,然后通知N32,N32接到通知后將N26標(biāo)記為它的前序節(jié)點(predecessor)。如下圖:

然后N26修改路由表,如下圖:

下一次N21運行stabilize()詢問其后繼節(jié)點N32的前序節(jié)點是不是還是自己,此時發(fā)現(xiàn)N32的前序節(jié)點已經(jīng)是N26:

于是N21就將后繼節(jié)點修改為N26,并通知N26自己已經(jīng)將其設(shè)置為后繼節(jié)點,N26接到通知后將N21設(shè)置為自己的前序節(jié)點。

這個加入操作會帶來兩方面的影響:

1)正確性方面:當(dāng)一個節(jié)點加入系統(tǒng),而一個查找發(fā)生在stabilization結(jié)束前,那么此時系統(tǒng)會有三個狀態(tài):

A.所有后繼指針和路由表項都正確時:對正確性沒有影響。

B.后繼指針正確但表項不正確:查找結(jié)果正確,但速度稍慢(在目標(biāo)節(jié)點和目標(biāo)節(jié)點的后繼處加入非常多個節(jié)點時)。如下圖:

C.后繼指針和路由表項都不正確:此時查找失敗,Chord上層的軟件會發(fā)現(xiàn)數(shù)據(jù)查找失敗,在一段時間后會進(jìn)行重試。

總結(jié)一下:節(jié)點加入對數(shù)據(jù)查找沒有影響。

2)效率方面:當(dāng)stabilization完成時,對查找效率的影響不會超過O(log N) 的時間。當(dāng)stabilization未完成時,在目標(biāo)節(jié)點和目標(biāo)節(jié)點的后繼處加入非常多個節(jié)點時才會有性能影響。可以證明,只要路由表調(diào)整速度快于網(wǎng)絡(luò)節(jié)點數(shù)量加倍的速度,性能就不受影響。

4.Chord節(jié)點失敗的處理

我們可以看出,Chord依賴后繼指針的正確性以保證整個網(wǎng)絡(luò)的正確性。但如圖,若N14, N21, N32同時失效,那么N8是不會知道N38是它新的后繼節(jié)點。為了防止這樣的情況,每個節(jié)點都包含一個大小為r的后繼節(jié)點列表,一個后續(xù)節(jié)點失效了就依次嘗試列表中的其他后繼節(jié)點。可以證明,在失效幾率為1/2的網(wǎng)絡(luò)中,尋找后繼的時間為O(log N) 。

5.Chord的特征和應(yīng)用

特征:去中心化,高可用度,高伸縮性,負(fù)載平衡,命名靈活。

應(yīng)用:全球文件系統(tǒng)、命名服務(wù)、數(shù)據(jù)庫請求處理、互聯(lián)網(wǎng)級別的數(shù)據(jù)結(jié)構(gòu)、通信服務(wù)、事件通知、文件共享。

參考文獻(xiàn):

Chord項目網(wǎng)址:http://pdos.csail.mit.edu/chord/

http://net.chinaunix.net/8/2008/07/28/1231438.shtml

轉(zhuǎn)載于:https://www.cnblogs.com/z-sm/p/5058176.html

總結(jié)

以上是生活随笔為你收集整理的Chord算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。