一致性哈希算法及其PHP实现的详细分析
典型的应用场景是:N服务器提供缓存服务,服务器需要负载平衡,请求平均分配给每个服务器。每台机器负责1个服务。
常用的算法得到的余数(hash()mod n)的散列结果:本机号码是从0到n-1,根据自定义的hash()算法,每个请求的哈希值进行采样的N,和剩余数我得到,然后请求分布式的机器编号、但算法如一个致命的问题存在,如果一个机器的停机时间,所以机器应在请求不能得到妥善处理,它将需要从服务器时,该算法从去除掉,这个时候会有(n-1)/数据缓存服务器需要重新计算,如果添加;机器,会有N /(N + 1)数据缓存服务器需要重新计算的系统,这通常是一个不可接受的凸点(因为这意味着大量的缓存故障或数据需要被传输)。因此,如何设计一个负载平衡策略以使受影响的请求尽可能的小呢
一致性哈希算法中采用Memcached,键值存储,BitTorrent的DHT和LVS。可以说,一致哈希算法是分布式系统负载均衡的首选算法。1、一致性哈希算法描述
下面是一个例子,在缓存一致性哈希算法。
对于一般的unsigned int类型的哈希算法的结果,所以对散列函数的结果应该是均匀地分布在{ 0232-1 },如果我们把一圈均匀切232分,根据hash(key)函数来计算服务器的哈希值(节点),并分发给0 ~ 232元。
相同的散列(key)函数用于查找需要存储并映射到圆的密钥的哈希值。然后从数据的位置到顺时针查找,数据被保存到找到的第一个服务器(节点)中。
一致散列原理示意图
当一个新的节点加入,只有第一节点,将节点添加到环上的顺时针方向的数据将受到影响。你删除一个节点时,节点开始顺时针方向的原始数据只删除环上会受到影响,所以一致性哈希是负载平衡的新结一个好的解决方案,删除的问题造成节点哈希碰撞。
虚拟节点(虚拟节点):引入虚拟节点的原因,因为服务器(节点)少(例如,只有3的服务器),hash(key)来计算环中的哈希值的节点分布不均匀(稀疏),仍然会有节点的负载平衡的问题。虚拟节点可以视为一份实际节点(复制品),它在本质上是相同的实际节点(重点是不一样的),通过引入虚拟节点,我们扩大数量的每个实际的服务器(节点)在一定比例(如200倍),并计算它的哈希值(关键)均匀分布于环,负载均衡,哈希值下降到虚拟节点实际上落在实际的节点。因为所有的交流虚拟节点复制成相同比例的虚拟节点的哈希值均匀地分布在环问题解决节点数量较少时。
虚拟节点对一致散列结果的影响
从上面,我们可以看到,当节点数为10,每房节点的虚拟节点的数目是实际节点的100-200倍,其结果是相当平衡。
文中第第三段:但是这个算法有致命的问题,如果一台机器停机,那么机器应该在请求中不能正常处理,它将需要从服务器上从算法中删除时被删除,这时将有(n-1)n服务器来缓存数据来计算;
为什么是(n-1) n解释如下:
例如,有3台机器,在3个站点上散列值1-6的分布是:
主持人1:14
主机2:25
主机3:36
如果你挂上一个,只有两个,而模是2,那么分布就变成了:
5主机1:13
6主机2:24
你可以看到数据,仍然不变的位置只有2:1, 2,位置变化有4,占总数的6,数据是4 6=2 3,那么,受影响的数据太多,太多的数据要从db重新加载到缓存,严重影响性能。
{一致散列法}
上面提到的散列需要模块,并且模块的数量相对较少,通常是加载的数量。一致散列法的本质是取较多的模块数,将1的2减少到32的功率,即最大的32位整数,这样就可以很容易地安排数据进行引导,该图相当直观。
接下来的部分是一致性哈希算法的PHP实现。