最近在面试或技术交流中,被提及到一致性hash,以前看的大都已经忘了,今晚回头又看了一遍,发篇文章总结一下以提醒自己,在学习新知识的同时,也不能把学过的给丢了,感谢阅读~
一、算法实现原理:
将机器节点和key值都按照相同的hash算法映射到一个0-2^32 的圆环上。当有一个写入缓存的请求到来时,计算key值k对应的hash值hash(k),如果该值正好对应之前某个机器节点的Hash值,则直接写入该机器节点,如果没有对应的机器节点,则顺时针查找下一个节点,进行写入,如果超过2^32还没有找到对应节点,则从0开始找(因为是环状结构)
经过一致性哈希算法散列之后,当有新的机器加入时,将只影响一台机器的存储情况。
-
如新加入节点H在BC之间,则原先由C处理的数据可能移除到H处理,而其他所有的处理情况都 保持不变,表现出很好的单调性。
-
而当删除一台机器,如删除C节点,此时原先由C处理的数据移除至D节点,而其他节点的处理情况仍然不变。
-
而由于在机器节点散列和缓冲内容散列时都采用同一种散列算法,因此也很好地降低了分散性和负载。
-
而通过引入虚拟节点的方式,也大大提高了平衡性。
-
虚拟节点”( virtual node )是实际节点(机器)在 hash 空间的复制品( replica ),一实际个节点(机器)对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以hash值排列。
-
数据的存储是沿着环的顺时针方向找一个虚拟节点,而每个虚拟节点都会关联到一个真实节点。
二、一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
1、平衡性(Balance):
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
2、单调性(Monotonicity):
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
3、分散性(Spread):
在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
4、负载(Load):
负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷
三、应用场景:
分布式缓存
具体参考文章:一致性哈希算法(Consistent Hashing)
参考资料:
1、一致性hash算法实现:http://blog.huanghao.me/?p=14
网友评论