最近公司在招人,我们准备的问题中有一道是关于一致性hash算法的问题,只有一些面试者能够回答上来,而且答的也不是很全面,有的面试者只是听说过,有的连听都没听过,下面我把一致性hash算法整理一下分享给大家
一 .算法背景(作为理解,不在面试范围)
一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用
二.应用场景
一致性Hash用于分布式缓存系统,将Key值映射到具体机器Ip上,并且增加和删除1台机器的数据移动量较小
比如你有 N 个 redis 服务器(后面简称 redis ),那么如何将一个对象 object 映射到 N 个 redis 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache
求余算法: hash(object)%N
这种通用的计算方法有什么问题呢?
1. 一个 redis 服务器 x 宕 掉了,这样所有映射到 redis x 的对象都会失效,怎么办,需要把 redis x 从 redis集群中移除,这时候 redis服务器 是 N-1 台le,那么对应映射公式变成了 hash(object)%(N-1) ;
2.还有一种情况是由于访问量增多,需要添加 redis ,这时候 redis 是 N+1 台,映射公式变成了 hash(object)%(N+1) ;
1 和 2 意味着什么?这意味着突然之间几乎所有的 redis缓存都失效了。对于服务器而言,这是一场灾难,所有的访问都会直接冲向后台服务器,对后台服务器造成压力,甚至是后台服务器瘫痪。
如何解决上面的问题呢?一致性hash算法就派上用场了
一致性Hash算法也是使用取模的方法,只是,刚才描述的取模法是对服务器的数量进行取模,而一致性Hash算法是对2^32取模,什么意思呢?简单来说,一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1(即哈希值是一个32位无符号整形),整个哈希环如下
整个空间按顺时针方向组织,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、5、6……直到2^32-1,也就是说0点左侧的第一个点代表2^32-1, 0和2^32-1在零点中方向重合,我们把这个由2^32个点组成的圆环称为Hash环。
那么,一致性哈希算法与上图中的圆环有什么关系呢?我们继续聊,以之前描述的场景为例,假设我们有4台缓存服务器,node1、node2、node3,node4,那么,在生产环境中,这4台服务器肯定有自己的IP地址或主机名,我们使用它们各自的IP地址或主机名作为关键字进行哈希计算,使用哈希后的结果对2^32取模,可以使用如下公式示意
hash(node1的IP地址) % 2^32
通过上面公式算出的计算一定能得到一个0到2^32-1之间的整数,我们就用得出的整数,代表服务器node1,既然这个整数肯定处于0到2^32-1之间,那么,上图中的hash环上必定有一个点与这个整数对应,我们刚才已经说过了,使用这个整数代表服务器node1,那么,服务器node1就可以映射到这个环上了,其他服务器一次类推即可得到相应的位置。
接下来使用如下算法定位数据访问到相应服务器: 将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,遇到的第一台服务器就是该数据应该映射到的服务器,如图:
三.一致性hash算法的容错性和扩展性
我想看了上面的例子大家应该已经理解了一致性hash的优势了,如果服务器node1节点宕掉,那么object1的数据会根据规则映射到最近的服务器node3上,同理如果增加一台服务器那么影响的也只是一小部分数据,一小部分数据会跟着规则迁移到新增服务器上
如上就是我们面试过程中想要得到的回答,今天就整理到这里了,大家有什么不同的观点欢迎评论指正,我是【不爱八阿哥】如果你觉得有用,记得关注我同时把知识分享给大家吧!!
本文暂时没有评论,来添加一个吧(●'◡'●)