首页 > 代码库 > 一致性hash

一致性hash

一致性hash算法思路是将整个哈希值空间组织成一个虚拟的圆环。并通过hash算法增加相应服务节点(通过ip计算hash)组成服务节点圆环。

(如果有我们要做5个物理节点,每一个节点做5个虚拟节点,通过hash算法将物理节点的ip+虚拟节点标识,将转换成25个hash值,这些值就是服务节点在虚拟圆环的相应位置。

  • 增加key时,先计算key的hash值,然后按顺时针方向,找最接近这个hash值得服务节点。并将key放入该服务节点。
  • 删除服务节点时,将该服务节点的key,按顺时针方向查找近期的服务节点,并将key放入该服务节点;
  • 增加服务节点时,通过hash算法计算相应的hash坐标。并按顺时针方向找到近期的服务节点。迭代该节点元素。将hash值小于等于新增服务节点的元素进行又一次定位,定位至新增服务节点;

附录:
良好的一致性hash算法,须要满足一下几点要求:平衡性(Balance)、单调性(Monotonicity)、分散性(Spread)、负载(Load)、平滑性(Smoothness)

平衡性(Balance)
平衡性是指哈希的结果可以尽可能分布到全部的缓冲中去,这样可以使得全部的缓冲空间都得到利用。

非常多哈希算法都可以满足这一条件。

单调性(Monotonicity)
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲区增加到系统中,那么哈希的结果应可以保证原有已分配的内容可以被映射到新的缓冲区中去,而不会被映射到旧的缓冲集合中的其它缓冲区。简单的哈希算法往往不能满足单调性的要求,如最简单的线性哈希:x = (ax + b) mod (P),在上式中,P表示全部缓冲的大小。

不难看出,当缓冲大小发生变化时(从P1到P2)。原来全部的哈希结果均会发生变化,从而不满足单调性的要求。哈希结果的变化意味着当缓冲空间发生变化时,全部的映射关系须要在系统内全部更新。而在P2P系统内。缓冲的变化等价于Peer增加或退出系统。这一情况在P2P系统中会频繁发生,因此会带来极大计算和传输负荷。单调性就是要求哈希算法可以应对这样的情况。

分散性(Spread)
在分布式环境中,终端有可能看不到全部的缓冲,而是仅仅能看到当中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,终于的结果是同样的内容被不同的终端映射到不同的缓冲区中。这样的情况显然是应该避免的,由于它导致同样内容被存储到不同缓冲中去。减少了系统存储的效率。

分散性的定义就是上述情况发生的严重程度。

好的哈希算法应可以尽量避免不一致的情况发生,也就是尽量减少分散性。

负载(Load)
负载问题实际上是从还有一个角度看待分散性问题。既然不同的终端可能将同样的内容映射到不同的缓冲区中。那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。

与分散性一样。这样的情况也是应当避免的。因此好的哈希算法应可以尽量减少缓冲的负荷。

平滑性(Smoothness)
平滑性是指缓存server的数目平滑改变和缓存对象的平滑改变是一致的。

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

一致性hash