分布式哈希和一致性哈希是分布式存储和p2p网络中说的比较多的两个概念了。介绍的论文不少,这里作一个入门性质的介绍。php
分布式哈希(DHT)
两个key point:每一个节点只维护一部分路由;每一个节点只存储一部分数据。从而实现整个网络中的寻址和存储。
DHT只是一个概念,提出了这样一种网络模型。而且说明它是对分布式存储颇有好处的。但具体怎么实现,并非DHT的范畴。html
一致性哈希:
DHT的一种实现。本质仍是一个哈希算法。回想平时咱们作负载均衡,按querystring签名对后端节点取模是最简单也是最经常使用的算法,但节点的增删后所形成的问题显而易见,原有的请求几乎都落不到同一台机器上。优化一点的是carp算法(用机器ip和querystring一块儿作hash,选取hash值最小的一台),只让1/n的数据受到影响。
一致性哈希,彷佛最先提出是在分布式cache里面的,让节点震荡的时候,影响最小,以提升分布式cache的命中率。不过如今更多的应用在分布式存储和p2p系统里面。算法
一致性哈希也只是提出四个概念和原则,并无说起具体实现:后端
一、balance:哈希结果尽量的平均分散到各个节点上,使得每一个节点都能获得充分利用。网络
二、Monotonicity:上面也说了,若是是用签名取模算法,节点变动会使得整个网络的映射关系更改。若是是carp,会使得1/n的映射关系更改。一致性哈希的目标,是节点变动,不会改变网络的映射关系。负载均衡
三、spread:同一份数据,存储到不一样的节点上,换言之就是系统冗余。一致性哈希致力于下降系统冗度。分布式
四、load:负载分散,和balance实际上是差很少的意思,不过这里更可能是指数据存储的均衡,balance是指访的均衡。优化
Chord算法:
一致性哈希有多种实现算法,最关键的问题在于如何定义数据分割策略和节点快速查询。编码
chord算是最为经典的实现。cassandra中的DHT,基本是chord的简化版。spa
网络中每一个节点分配一个惟一id,能够经过机器的mac地址作sha1,是网络发现的基础。
假设整个网络有N 个节点,而且网络是呈环状。两个节点间的距离定义为节点间下标差。每一个节点会存储一张路由表(finger表),表内顺时针按照离本节点二、四、八、1六、32.……2i的距离选定log2N个其余节点的ip信息来记录,主要是为了查询加速。
存储:数据被按必定规则切割,每一份数据也有一个独立id(查询key),而且和节点id的值域是同样的。而后查找节点,若是存在和数据id同样的节点id,则将这份数据存在该节点上;若是不存在,则存储到离该数据id距离最近的节点上。同时,为了保证数 据的可靠性,会顺时针往下找K个冗余节点,存储这份数据。通常认为K=3是必须的。
下图简单描述了一个chord网络的部署,绿色节点为机器,编码为hash值。N0节点的finger表能够看出N0节点的路由规则,其余节点也有相似的finger表。蓝色节点为数据,根据hash值找到最近的节点并存储。虚线所指是表示冗余存储。
查询:先从本身的路由表中,找一个和数据id距离最近、而且存活在网络中的节点next。若是该节点的 id巧合和数据id相等,那么恭喜你。若是不相等,则到next进行递归查找。通常或须要通过屡次查询才能找到数据所在的节点,而这个次数是能够被证实小于等于log2N的。
在这个查询的过程当中就体现了路由表的选取优点了,实际上是实现了一个二分查找,从每一个节点来观察网络,都是将网络分红了log2N块,最大一块里面有N/2个节点。路由表里面实际上是记录了每一块的第一个节点。这样每一次查询,最少排除了一半的节点。保证在 log2N次内找到目标节点。
下图简单展现了从N0节点查找N21节点的一个数据的过程,经过finger表通过2跳到达目的地。
新增一个节点i:须要预先知道网络中已经存活的一个节点j,而后经过和节点j交互,更新本身和其余节点的路由表。而且,须要将离本身距离最近的节点中的数据copy过来,以提供数据服务。
损失一个节点:路由算法会自动跳过这个节点,而且依靠数据的冗余来持续提供服务。
KAD算法(Kademlia)
kad算法实际上是在chord上作的优化。主要是两个点:
一、用二进制(32/64/128)表示一个节点的id,两节点的id异或运算获得节点间的距离。
二、 每一个节点保持的路由信息更丰富,一样是将整个网络按照划分红log2N份,在chord中,是保持log2N个路由节点,但在kad里面,是保存了 log2N个队列。每一个队列长度为配置值K,记录网络中对应节点区域的多个节点,而且根据活跃时间对这些节点进行换入换出。
第一点是方便进行网络划分,节点按照二进制中每一bit的0或1建成一棵二叉树。
第二点是使得节点查询更迅速。从分割状况咱们就能够得知,最坏状况不会差于chord,但保存更多的节点使得命中几率更高。另外队列中根据活跃时间进行换入换出,更有利于在p2p这种节点变动频繁的网络中快速找到有效的节点。
关于kad的介绍,这篇文章讲的比较详细wenku.baidu.com/view/ee91580216fc700abb68fcae.html