关于一致性hash算法的解释和应用场景,博客中以已经出现了许多非常优秀的文章解释,这里放一个解释比较清楚的博客文章如果不太了解一致性hash算法是什么可以点击了解一下,本文主要融合一致性hash算法思想去简单解决我们工作中遇到的问题。
在程序设计思想中我们知道要时刻面对变化,而一致性hash算法的出现就是应对hash算法对特定数值取模时这个特定数值带来的变化。用我们工作中比较常见的一个场景数据库分表来举例:
场景一:我们数据库有一张文章表数据量超过1000万条数据,导致我们查询效率低下,所以技术部决定对这表表进行拆分,考虑到目前公司的发展情况,我们决定把这张表拆分成3份,那么我们对文章表中主键id做hash运算然后对3取模如:hash(id)%3 如果取模得到的值为1就把数据放入文章表1中,如果取模得到2就把数据放入文章表2中,以此类推我们成功把原来的一张表拆分成了3张完美解决了当下的问题。
场景二:万万没想到不到一年的时间公司业务发展迅猛数据量暴增,原来的3张文章表也不够用了,还要扩张表怎么办?如果要扩张表就需要对文章表主键进行hash重排,然后重新分配,可以想像那工作量和不确定性是多么大,基本上不会这样做。所以基本无解。
场景三:吸取场景二的教训,然后加上学了一致性hash算法以后,开始用该算法去实现自己的分表操作,可是问题来了,算法我是知道了,可是真正实现起来对一般小公司的技术人员来讲还是有一定难度的,真的有一种道理我都懂,可是依然过不好这一生的感觉,哈哈。
最后根据一致性hash算法的思想和自己的理解我想出了一个中间方案,我就推测公司的发展情况我预估它5年后可以达到20张文章表,但目前需求我们需要从3张表扩展到6张表,然后我们可以计算hash(id)%20将取模后的结果分配到这6张表中,如下表分配:
对于hash取模后的值对应上表进行分配,如值为4我们就把该记录分配到文章表二中, 值为15我们就把记录放到文章表5中,以此类推,如果哪天我们需要继续扩展表到7张怎么办呢?我们就可以把节点15, 16从文章表5中放到文章表7中,如下图:
这样分配以后,其他文章表不动我们只需要对文章5中的数据进行重新hash,然后重新分配到表5或者表7中即可完美避免hash重排的命运。
在此文章中只是对分表做hash分配,如果上升到机器层面,我们是不是可以对配置高的机器多分配节点,配置低的机器少分配节点,有点根据权重分配的感觉了,哈哈。
如果想对分布式系统相关的中间件有个大概的认识 李庆旭的分布式系统设计实践 这本书真的非常适合你,这是我为数不多连续花两个晚上看完的书籍,给你上帝的视角去看待分布式系统的设计和各中间件的由来和解决什么问题,受益颇深。