概述
最近一个工作4年的程序员,去美团面试,被面试官问到一个一致性hash算法的问题他没回答上来,然后跑过来找我希望我能帮他分析一下这个问题。
具体问题是:“说说你对一致性Hash算法的理解”
问题解答
一致性hash,是一种比较特殊的hash算法,它的核心思想是解决在分布式环境下,hash表中可能存在的动态扩容和缩容的问题。
为什么会出现一致性hash
一般情况下,我们会使用hash表的方式以key-value的方式来存储数据,但是当数据量比较大的时候,我们就会把数据存储到多个节点上,(如图)然后通过hash取模的方法来决定当前key存储到哪个节点上。
这种方式有一个非常明显的问题,就是当存储节点增加或者减少的时候,原本的映射关系就会发生变化。
也就是需要对所有数据按照新的节点数量重新映射一遍,这个涉及到大量的数据迁移和重新映射,迁移代价很大。
一致性hash的工作原理
而一致性hash就是用来优化这种动态变化场景的算法,它的具体工作原理也很简单。首先,一致性Hash是通过一个Hash环的数据结构来实现的,(如图),这个环的起点是0,终点是2^32-1。也就是这个环的数据分布范围是[0,2^32-1]。
(如图)然后我们把存储节点的ip地址作为key进行hash之后,会在Hash环上确定一个位置。
接下来,(如图)就是把需要存储的目标key使用hash算法计算后得到一个hash值,同样也会落到hash环的某个位置上。
然后这个目标key会按照顺时针的方向找到离自己最近的一个节点进行数据存储。
为什么一致性Hash比普通hash算法好
假设现在需要新增一个节点(如图)node4,那数据的映射关系的影响范围只限于node3和node1,只有少部分的数据需要重新映射迁移就行了。
如果是已经存在的节点node1因为故障下线了(如图),只那只需要把原本分配在node1上的数据重新分配到node2上就行了。同样对数据影响的范围非常小。
所以,一致性hash算法的好处是扩展性很强,在增加或者减少服务器的时候,数据迁移范围比较小。
另外,在一致性Hash算范里面,为了避免hash倾斜导致数据分配不均匀的情况,我们可以使用虚拟节点的方式来解决。
面试点评
一致性Hash算法在实际应用中还是比较常见的。
所以在面试的时候,会围绕这个方面设计一些技术面试题。
虽然很多开源框架都提供了一致性hash算法的实现,但建议大家可以读一读源代码。