传统的取模方式固定均衡分配数据,在增加节点的时候,都需要做搬迁,成本太高然而在使用一致性哈希方式最关键的区别就是对节点和数据,都做一次哈希运算,然后比较节点和数据的哈希值,数据取和节点最相近的节点做为存放节点。这样就保证当节点增加或者减少的时候,影响的数据最少
具体算法过程为:先构造一个长度为0~232的整数环(这个环被称作一致性Hash环),根据节点名称的Hash值(其分布范围同样为0~232)将节点放置在这个Hash 环上。然后根据KEY值计算得到其Hash值(其分布范围也同样为0~232 ),然后在Hash环上顺时针查找距离这个KEY的Hash值最近的节点,完成KEY到节点的Hash映射查找。
考虑到分布式系统每个节点都有可能失效,并且新的节点很可能动态的增加进来,如何保证当系统的节点数目发生变化时仍然能够对外提供良好的服务,尤其实在设计分布式缓存系统时,如果某台服务器失效,对于整个系统来说如果不采用合适的算法来保证一致性,那么缓存于系统中的所有数据都可能会失效(即由于系统节点数目变少,客户端在请求某一对象时需要重新计算其hash值(通常与系统中的节点数目有关),由于hash值已经改变,所以很可能找不到保存该对象的服务器节点),因此一致性hash就显得至关重要,良好的分布式cahce系统中的一致性hash算法应该满足以下几个方面:
平衡性(通过hash的KEY,如果移除其中服务器则引入了虚拟节点)
分散性(相同内容被存储到不同缓冲中去,降低了系统存储的效率)
平滑性(缓存服务器的数目平滑改变和缓存对象的平滑改变是一致)
一致性哈希将整个哈希值空间组织成一个虚拟的圆环(环形哈希空间)
通过Hash算法得到对应的KEY值,映射到环中 顺时针转动存储服务结点种
比如你有 N 个 cache 服务器,那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ;
求余算法: hash(object)%N
环形结构
add节点 逆时针遍历