一个良好的分布式哈希方案,应该具有良好的单调性,即服务节点的增减不会造成大量哈希的重新定位。
首先,一致性哈希算法会将整个哈希值空间理解成一个环,其取值范围是 \(0\sim2^{32}-1\) 共 4G 的整数空间:
然后,将所有的服务器进行哈希,最终落在这个一致性哈希环上。现在假设有 A、B、C 三台服务器,它们经过哈希后,相应的位置如下:
对客户端进行负载时,先通过哈希输入值得到一致性哈希环上的一个哈希值,然后顺着顺时针方向,所遇到的第一台服务器,就是最终所需要负载到的服务器。如下图,现在有 1、2、3、4 四个客户端分别被哈希到该环上的不同位置,可见,最终 Client1 会被分配给 Server C,Client 2 和 Client3 会被分配给 ServerB,Client4 会被分配给 ServerA:
对于在简单哈希算法中所存在的“重新定位”的问题,在一致性哈希算法中会得到相应的解决。
假如此时 ServerC 挂掉了,那么原来在 ServerB 上的 Clinet2 和 Client3 依然会在 ServerB 上,Client4 也是一样,仅仅只有 Client1 改变到了 ServerB 上:
而假如此时新增加了一台服务器 ServerD,如下图所示,那么 Client1、Client2、Client3 都不会收到影响,仅仅只有 Client4 受到了影响:
综上所述,一致性哈希算法的容错性和可扩展性的分析如下:
- 容错性:当某个服务器挂掉时,仅仅只有分发在所挂掉的服务器上的客户端会受到影响;
- 可扩展性:当增加一台服务器时,受影响的客户端仅仅只有在新增加的服务器沿着逆时针方向所碰到的上一台服务器之间的客户端;
可见,对于一致性哈希算法而言,服务节点的增减并不会造成大量哈希的重新定位。
但是,如果服务器在哈希到哈希环上时如果过于紧凑,那么服务器的压力就不能做到尽量平均分配,如下图所示,可见,四个客户端都会被分配给 ServerB,而 ServerA 上却并未分配客户端:
为了使得在哈希环上的服务器节点分配更加分散,可以使用【虚拟节点】的方法来进行处理。虚拟节点即将同一个主机在哈希环上设置多个虚拟主机,如下图所示中的服务器 A 和 服务器 B,在每个虚拟节点中存储的是真实的物理主机地址:
虚拟节点的引入就是为了防止物理节点过少,导致哈希处理后,在一致性哈希环上挤在一起,导致某一台服务器负载太多,其它的服务器一直很空闲。
标签:环上,算法,哈希,一致性,服务器,节点,客户端 From: https://www.cnblogs.com/tuilk/p/17045134.html