一致性hash算法通俗描述

背景:
	当客户端调用redis缓存集群(比如3台)存取数据时,
	如果客户端采用普通的hash求余(id%3)的算法,来计算该数据应该由哪台redis服务器存取, 
	当算法是:id%机器数,redis服务器和id的对应关系有:
		 id%3时===>redis1:0/3/6/9,redis2:1/4/7,redis3:2/5/8,
	当redis集群中一台服务器 redis3 down掉后,hash值从id%3变成了id%2,变成:
		 id%2时===>redis1:0/2/4/6/8,redis2:1/3/5/7
	可见很多数据需要迁移:2/3/4/5/8/9都需要迁移


设想一下:
怎么在服务器down掉后,尽量少地迁移数据呢?
	 如果down掉的redis服务器不会影响其他redis服务器上数据存储,是不是需要迁移的数据就会变少呢!
	 ===>当redis3down掉了,只会影响redis3上的数据,那需要迁移的数据就只有redis3上的2/5/8
为了达到上面的目的,一致性hash算法就该出场了。


实现:
一致性hash算法为了达到这个目的,引入了一个虚拟节点的概念。
之前咱们是通过id求余,计算出需要将id放到哪台redis服务器的,即对应关系是:
	id===>服务器
	比如:id%redis服务器数量=对象存储的redis服务器序号
	id=4,redis有3台,则4%3=1,所以对象放到第一台服务器redis1。
在添加虚拟节点作为中间层之后,现在咱们不再把id和服务器对应起来,而是通过中间层联系起来
	id===>虚拟节点序号===>服务器
	比如:还是id为0->9的10个对象;redis服务器还是3台;假定中间层序号是z0->z9
	1)将id映射到环上,假如环上节点号的算法是:id%虚拟节点数,则分别一个id对应一个节点:
        0=>z0,1=>z1,2=>z2 ...z9=>z9
	2)将redis服务器映射到环上,假如环上节点号的算法是:redis服务器序号*3,则有:
        redis1=>z3,redis2=>z6,redis3=>z9
	3)环上的节点由哪台redis服务器管理呢?我们可以定义规则:从该节点开始,在环上顺时针查找,
    找到的第一个服务器管理这个节点。
	所以redis服务器需要管理的环上的区域有:
		 redis1:z0/z1/z2/z3  redis2:z4/z5/z6  redis3:z7/z8/z9
		 对应的id也是:
		 redis1:0/1/2/3  redis2:4/5/6  redis3:7/8/9
	则服务器redis3 down掉后,
		 1)中的对象id在环上的位置不变,还是0=>z0,1=>z1,2=>z2 ...z9=>z9
		 2)中redis1 和redis2在环上的位置也不会变,还是redis1=>z3,redis2=>z6
	所以只有redis3区域的id(7/8/9)需要改变。
	这时id(7/8/9)在环上顺时针查找的节点是redis1,所以redis3上的数据会放到redis1上。
 
   大功告成!这里的说法有些地方不太准确,主要是为了说明过程,想了解具体过程的可以看看其他文章的准确描述

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值