0
点赞
收藏
分享

微信扫一扫

一致性 hash

Hyggelook 2022-01-24 阅读 104

分布式系统中,多个节点间实现请求的负载均衡, 如果部分实例由于一些特殊的原因宕机或者需要扩容,这个时候就涉及到部分请求重新分发的问题。

为了最小化请求重新分发,引入了一致性 hash 算法。

先看下传统的 hash 算法解决请求分发问题的过程。

hash 

hash 算法大家应该很熟悉了,就是将不定长的数据经过计算后输出定长的结果。

如果在分布式系统中使用 传统hash 方法来分发请求,

  server =  hash(key) % n 

这会带来两个问题:

  1. 一旦服务器节点数 n 发生伸缩,就需要重新计算所有 hash ,会大大的消耗服务器性能从而降低整个系统的吞吐量。

  2. 可能出现分布不均匀问题,部分节点负载过高,部分节点负载过低。

为了解决传统 hash 方法带来的问题,1997年麻省理工提出了一致性 hash 算法( 也称hash 环)。

一致性 hash

也称作 hash 环,一致性哈希是一种特殊的哈希技术,当哈希表的大小发生变化时,平均只需要重新映射n/m个键,其中n是键的数量,m是插槽的数量。

具体工作过程:

  1. 请求的 key 进行 hash 计算后放入环中;

  2. 服务器 ip 进行 hash 计算后放入环中;

  3. 将 hash(key) 和 hash(ip)  相同的请求分发到对应的服务器,如果找不到相同的值,则按照顺时针方向找到最近的节点来处理请求。

注意,这里的hash 计算已经和节点数无关了,2^32 表示的是环上虚拟节点的个数。

position = hash(key) % (2^32 ).

这个时候,服务器节点数发生伸缩,只需要重新做部分计算即可。

在0号机器和1号机器间添加新的节点4号机器时,只需要重新计算 k1 和 k2 的hash 即可。

如果发生宕机,假设是2号机器宕机,这个时候执行需要将之前分发在2号机器的k3重新分发到 0号机器即可。

最后,为了解决请求分布不均匀问题,可以为每台服务器增加多个虚拟节点随机hash 到不同的位置 , 环中的服务器节点数越来越多,请求的分发也就越来越均匀。

应用

分布式系统经常会用到一致性hash,比如 cassandra 集群中 客户端请求分发过程、分布式缓存:redis、memcached 他们的客户端包已经封装了一致性hash算法,比如 jedis。

 值得一提的是, redis 3.0 后当redis 作为数据存储使用时,采用了hash 槽的方式(见之前的文章《Redis 高可用》)。

举报

相关推荐

0 条评论