一致性哈希算法及其应用

一致性哈希 

普通的哈希算法使用取余操作:hash(o) mod n,其中 n 代表机器的数量。如果在集群中新增加一个节点时,计算公式会变为:hash(o) mod (n+1);在集群中删除一个机器时,计算公式变为:hash(o) mod (n-1)。所以当集群中机器数量有所变化时,几乎所有的 Object 的哈希值都会改变。一致性哈希可以保证当从集群中删除一台机器时,仅仅保存在该机器上的 Object 的值会变化;当集群中增加一台机器时,也仅仅是非常小的一部分 Object 的哈希值会发生改变。

一致性哈希的值一般使用 32bit 保存,所以哈希值的空间范围是0~2^32-1,并且2^32-1后面的值是0 ,如图所示是一个封闭的圆圈。

在这个圆圈上会映射两种元素的哈希值,一种元素是Object的哈希值,如图2所示是映射4个object;另一种元素是cache的哈希值,即计算机节点的哈希值,如图3所示是映射3个cache。

当从集群中删除一个节点,如删除 CacheB,则缓存在 CacheB 上的 Object 将会移动到 CacheC 上,如图4;当集群中新增加一个节点时,如增加 CacheD,则在CacheB和CacheD之间的Object会从CacheC上转移到CacheD上,如图5。

如果节点数量较少时,还是会出现数据分布不均匀的情况,通过使用虚拟节点的方法可以解决。虚拟节点是将一个真实的cache在圆圈上复制几份作为虚拟节点,如图6。当集群中增加一个真实cache 时,对应的增加一定数量的虚拟节点,当集群中删除一个真实的cache时,其所对应的虚拟节点都会被删除。

Memcache

一致性哈希可以用于Memcache。

Memcache是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。其分布式由客户端实现。每个客户端维护一个服务器池,通过一致性哈希算法,将数据比较均匀地分布在池中的服务器上。

Memcached 将所有的数据放在内存中,不具备数据持久化的功能,当一台机器宕机时,内存里面保存的数据将会全部丢失。

Memcache数据的分布方法主要采用的是一致性hash算法,算法流程如下:

  1. 构造一个长度为2^32的整数环,然后根据服务器节点的hash值,将服务器节点分布到这个环上。
  2. 当有需要缓存的数据时,根据该数据的key值计算得到hash值,并将其映射至环上。
  3. 在环上顺时针查找与该hash值最近的服务器节点,从而完成key到服务器节点的映射,并将数据存储在该服务器节点上。
  4. 如果超过2^32次方仍然找不到服务器,则将数据保存到第一台服务器上。

通过该算法有效的减少了服务器节点增减导致的缓存重新分布。

另外,由于通过一般的hash函数,服务器的映射地点的分布可能会不均匀,故采取虚拟节点的方法,为每个物理服务器节点设置多个“逻辑节点”,可以进一步减小服务器节点增减导致的缓存重新分布。 

猜你喜欢

转载自blog.csdn.net/shimadear/article/details/84450210