一致性哈希算法是分布式系统中经常使用的算法。但相信不少朋友都是知其然而不知其因此然。本文将尽可能使用易懂的方式介绍一致性哈希原理,而且经过具体应用场景来帮助你们深刻这个概念。html
Hash,通常翻译作散列、杂凑,或音译为哈希,是把任意长度的输入(又叫作预映射pre-image)经过散列算法变换成固定长度的输出,该输出就是散列值。算法
一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,主要是为了解决因特网中的热点(Hot spot)问题。目前这一思想已经扩展到其它的领域,而且在实践中获得了很大的发展。服务器
经典哈希方法:老是假设内存位置的数量是已知且固定不变的。由于hash映射依赖节点/内存位置,因此若是须要变化集群,须要从新计算每个key的哈希值。哈希表(服务器数量)大小的变动实际上干扰了 全部映射。分布式
一致性哈希:某种虚拟环结构。位置数量再也不固定,环有无限数量的点,服务器节点能够放置在环上的随机位置。哈希表(服务器数量)大小改变会致使 只有 一部分请求(相对于环分配因子)会受到特定的环变动的影响函数
从拗口的技术术语来解释,一致性哈希的技术关键点是:按照经常使用的hash算法来将对应的key哈希到一个具备2^32次方个桶的空间中,即0 ~(2^32)-1的数字空间。咱们能够将这些数字头尾相连,想象成一个闭合的环形。spa
用通俗白话来理解,这个关键点就是:在部署服务器的时候,服务器的序号空间已经配置成了一个固定的很是大的数字 1~2^32。服务器能够分配为 1~2^32 中任一序号。这样服务器集群能够固定大多数算法规则 (由于序号空间是算法的重要参数),这样面对扩容等变化只是对部分算法规则作调整。具体会参见后面实例详细说明。.net
如何决定哪一个请求将由哪一个服务器节点来处理?翻译
从理论上来讲,每一个服务器节点“拥有”哈希环的一个区间,进入该区间的任何请求将由同一服务器节点来处理。htm
blog
若是其中一个服务器节点出现故障,下一个服务器节点的区间就变宽,进入该区间的任何请求都将进入到新的服务器节点。这时候应该如何处理这些异常的请求?
一致性Hash的优点就在这里体现:须要从新分配的是仅仅这一个区间(与出现故障的服务器节点对应),哈希环的其他部分和请求/节点分配仍然不受影响。
你们都知道,梁山泊山下有四个酒店。分别是: 东山酒店 / 西山酒店 / 南山酒店 / 北山酒店
那么这四个酒店如何分配客人入住呢? 这里就能用到Hash算法,也能看到一致性哈希的好处。
梁山4个酒店,按照顺序其序号是1,2,3,4。
哈希函数:客人姓名笔画 / 4获得一个余数,客人按照余数分配到这4个酒店中
若是减小一个酒店,哈希函数就变成: 客人按照姓名笔画 / 3,而后客人按照这个新余数来分配酒店。全部客人都得从新分配酒店
若是增长一个酒店,哈希函数就变成: 客人按照姓名笔画 / 5,而后客人按照这个新余数来分配酒店。全部客人都得从新分配酒店
能够看到,若是有容量变化,则哈希函数和分配规则都要改变,这样就对总体机制形成了伤害。
预先就把服务器的序号空间(如今~将来)想好了,定为100个桶。就是在将来可见的年分内,100个确定够了(l梁山不管怎么扩大生产规模,哪怕扩招了10000个头领,山下也没有开设100个酒店的可能)。
客人姓名笔画/100. 这个是固定不变的! 由于100这个序号空间固定了,因此哈希函数和分配规则都基本固定了。
酒店1负责 hash(x)--> 1~20,即客人姓名笔画/100位于1~20之间。
酒店2负责 hash(x)--> 21~40,即客人姓名笔画/100位于21~40之间。
酒店3负责 hash(x)--> 41~60,即客人姓名笔画/100位于41~60之间。
酒店4负责 hash(x)--> 61~100,即客人姓名笔画/100位于61~100之间。
客人来了,姓氏笔画/100,获得余数。去余数对应的酒店住。好比余数3住到酒店1,余数22则住到酒店2......
若是该酒店出问题关门了,就去比全部 "比余数大的酒店" 中最小那个住。以此类推。好比酒店1挂了,就去酒店2,酒店2挂了去3。
若是最大酒店也出问题关门了,就转圈回到最小酒店住。即若是酒店4挂了去酒店1.
减小酒店。若是酒店3挂了,则原来去酒店3的客人去酒店4,原来去酒店4的客人仍是酒店4. 这样只有酒店4受到影响,1,2号酒店客人不用搬家。
增长酒店。若是增长了一个酒店5.则须要对 酒店/客人分配规则 作改变。让4号酒店负责61~80,5号酒店负责81~100。这样4号点原有部分客人要迁移到5号。
能够看出来,关键在于服务器的序号空间早就肯定了是一个之后也不会修改的大数字100。固然这是梁山。对于其余真实案例多是2^32。这样hash函数 (由于序号空间是算法一个重要参数) 能够保持不变,只有"分配规则" 须要根据实际系统容量作相应微调。从而对总体系统影响较小。
固然具体分配酒店的规则算法,是能够融入到hash中。即酒店号码可能就是21,41,61....
http://www.javashuo.com/article/p-aihsrxyr-cp.html
http://www.javashuo.com/article/p-dczpmtqp-mq.html
https://www.iteblog.com/archives/2499.html
http://www.zsythink.net/archives/1182/