在解决分布式系统中负载均衡的问题时候可使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的做用。可是普通的余数hash(hash(好比用户id)%服务器机器数)算法伸缩性不好,当新增或者下线服务器机器时候,用户id与服务器的映射关系会大量失效。一致性hash则利用hash环对其进行了改进。算法
为了能直观的理解一致性hash原理,这里结合一个简单的例子来说解,假设有4台服务器,地址为ip1,ip2,ip3,ip4。服务器
一致性hash是首先计算四个ip地址对应的hash值
hash(ip1),hash(ip2),hash(ip3),hash(ip3),计算出来的hash值是0~最大正整数直接的一个值,这四个值在一致性hash环上呈现以下图:负载均衡
如上图可知user1,user2的请求会落到服务器ip2进行处理,User3的请求会落到服务器ip3进行处理,user4的请求会落到服务器ip4进行处理,user5,user6的请求会落到服务器ip1进行处理。分布式
下面考虑当ip2的服务器挂了的时候会出现什么状况?当ip2的服务器挂了的时候,一致性hash环大体以下图:3d
根据顺时针规则可知user1,user2的请求会被服务器ip3进行处理,而其它用户的请求对应的处理服务器不变,也就是只有以前被ip2处理的一部分用户的映射关系被破坏了,而且其负责处理的请求被顺时针下一个节点委托处理。blog
下面考虑当新增机器的时候会出现什么状况?当新增一个ip5的服务器后,一致性hash环大体以下图:ip
根据顺时针规则可知以前user1的请求应该被ip1服务器处理,如今被新增的ip5服务器处理,其余用户的请求处理服务器不变,也就是新增的服务器顺时针最近的服务器的一部分请求会被新增的服务器所替代。ci
服务器ip1,ip2,ip3通过hash后落到了一致性hash环上,从图中hash值分布可知ip1会负责处理大概80%的请求,而ip2和ip3则只会负责处理大概20%的请求,虽然三个机器都在处理请求,可是明显每一个机器的负载不均衡,这样称为一致性hash的倾斜,虚拟节点的出现就是为了解决这个问题。路由
当服务器节点比较少的时候会出现上节所说的一致性hash倾斜的问题,一个解决方法是多加机器,可是加机器是有成本的,那么就加虚拟节点,好比上面三个机器,每一个机器引入1个虚拟节点后的一致性hash环的图以下:hash
其中ip1-1是ip1的虚拟节点,ip2-1是ip2的虚拟节点,ip3-1是ip3的虚拟节点。可知当物理机器数目为M,虚拟节点为N的时候,实际hash环上节点个数为M*N。好比当客户端计算的hash值处于ip2和ip3或者处于ip2-1和ip3-1之间时候使用ip3服务器进行处理。
上节咱们使用虚拟节点后的图看起来比较均衡,可是若是生成虚拟节点的算法不够好极可能会获得下面的环:
可知每一个服务节点引入1个虚拟节点后,状况相比没有引入前均衡性有所改善,可是并不均衡。均衡的一致性hash应该是以下图:
均匀一致性hash的目标是若是服务器有N台,客户端的hash值有M个,那么每一个服务器应该处理大概M/N个用户的。也就是每台服务器负载尽可能均衡