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的详细实施。