前沿
有时候想想,分布式领域真的很多东西都差不多,大家都会碰到,所以今天这个一致性hash是用在什么场景呢?看看比人的博客,我也需要有自己的思考的东西。
解决什么问题
一致性Hash算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。可以用来做负载均衡和扩容处理。
- 场景一:如果一个数据库表已经分库分表,有4张表,那么现在如何实现扩容,扩容到8张表?
- 场景二:8张表,如果要缩容,应该如何实现?
以上这些情况都可以通过 hash来解决,把数据hash 后,就可以实现扩容、缩容,新的问题:
- 扩容后,是不是所有数据都要重新hash?因为有些数据要被分到其他节点上去了
巧了,一致性Hash就可以解决这个问题。
如何解决
普通的hash无法解决这个问题,一致性hash为啥可以?一致性hash可以把节点映射到更多节点,并且是一个环形,以前是4台机器,4个节点,hash节点也是4个,现在通过一致性hash可以把映射400个节点出来,0-100属于节点1,100-200属于节点2等等,如图所示:
这样做有什么好处?一句话简单总结:影响最小、且操作空间大。以下几点:
- 如果扩容,只是圆环中的某一段分给了新节点,这样只影响来一个服务对应的节点数,其他节点不变
- 把数据进行hash赋给新节点,再把hash算法改掉,操作空间非常大,对业务无影响,无感知
- 如果实现完全的负载均衡,也可以更改节点到实际节点的映射关系
这里面最重要的一点就是对业务无感知,而且是部分数据hash,并不是全量数据hash,影响也小。这里不需要虚拟节点的概念,因为虚拟节点到实体节点还有一层hash关系,这样就不能保证扩容只影响一个节点数据。
不用一致性hash来做扩容可以嘛?我觉得是可以的,就一个超大数组+hash就可以完成,只不过一致性hash也具备这个能力,一致性hash的虚拟节点在负载均衡有用。
举例子啦
画图太费时间了,文字举例:我们有一张表,分表为4张,在要继续扩容,扩容到8张表
- 0-100节点给数据库1表
- 100-200节点给数据库2表
- 200-300节点给数据库3表
- 300-400节点给数据库4表
这个时候新增4张表,我们可以把之前分配给每个表的100个节点分成2个50节点,这样1张表的数据就分成了两份
- 先把数据同步来到新节点,这样只有一半的数据会被重定向去其他表,一半数据不变。
- 同步完成,替换为新的节点跟表的映射关系。
这样针对增删改查都比较方便。如果一个机器被缩容了,那么之前属于他的节点可能就失效了。
负载均衡
负载均衡可以用一致性hash来解决,一致性hash有一个问题,如果不是2的倍数扩容,就存在负载不均衡的问题,某些节点的请求量就多了,也叫数据倾斜问题。
基于此,有人提出虚拟节点的概念,意思就是将一台机器虚拟出很多节点,然后把这些节点放到hash环上,每台服务器的虚拟节点交替出现,网上看到的图片:
其实我有一个问题,为啥要用节点去生成虚拟节点?而且虚拟节点的分布也会导致不均衡的问题?完全可以不用这么做呀,完全可以固定hash环上的节点数量,通过对hash环上节点数字再hash就可以了,可以按照以下流程来分析:
- 现在有3个服务器,我们可以确定再hash的数字是m=3,hash环上一共有n=100个节点
- 新增一个机器,m=4,节点数字%m 就可以确定服务器位置
- 减少一台机器,m=2,节点数字%m 就可以确定服务器位置
这样也是比较均衡的,而且解决了虚拟节点分布的问题,唯一的问题是有可能n=7,m=5,这样有些节点再hash后,某些机器上服务会少一个调用,不是完全平均的,但是当n非常大的时候,这种问题可以忽略。当然hash环上的节点也可以称为虚拟节点。
优点缺点
看到一个有趣的一句话:用错了场景才是缺陷,用对了,那是特性。一致性hash主要是解决数据分布场景,普通的hash也是解决数据分布的场景。
优点:
- 1、均衡
- 2、将节点与Hash算法解耦,而且通过交错分配虚拟节点的方式解决了负载不均衡导致的缓存热点问题
缺点:
- 1、虚拟节点只是为了让请求散落更均匀而存在,节点数量变化时虚拟节点数量也会变化,这种耦合限制的hash算法的进一步优化。比如在只有少量节点的集群中出现宕机时,其虚拟节点仍然会把负载传递给下一个相邻节点。
- 2、hash映射比较固定,如果认为的要根据业务标签来过hash,如何实现?
这个问题很有意思,应该把业务标示放在中间件框架中嘛?当然另外的角度就是是否允许实现灵活,灵活意味这可以实现特殊场景的兼容,也就是定制化考虑,似乎慢慢很多中间件也会思考这方面问题,看具体业务环境和公司环境吧,属于决策的领域了。 - 3、不是完全的均匀负载
有一篇文章总结了hash的发展,其中用redis做例子讲解,大家可以看看Redis的一致性Hash算法演进及优缺点分析
。