一致性hash问题

提出问题

一个客户端访问服务端只能一直访问一台机器,因为有些用户数据就存放在这个服务器上,访问其他数据,这台机器上的用户数据就丢失,想利用算法解决这个问题。
分布式缓存的问题
可以利用一致性hash来解决问题

为啥不直接用hash

如果想将一些数据均匀的缓存在各个服务器上,那么一般是对数据的名字做hash运算,之后除以机器的数量,均匀打在不同的服务器上
而且下次访问这个数据的时候,由于数据的名字是相同的所以计算出的hash的值也是相同的,方便查找

但是hash算法有个问题,就是不方便扩容,在MySQL的分表中也有同样的问题。
如果服务器的数量从3扩充到了4,一开始6对3取模是0,打到了0号服务器上,现在6对4取模,打到了2号服务器上,这样查询到服务器出现了问题,所以不适合扩展,这样当缓存无法获取数据,如果当扩充服务器之后有大量的缓存出现失效的情况,也就是找不到对应的数据,就会造成缓存雪崩

原理

有个2^32次方的环,还是三台服务器
1.三台服务器想在换上找到自己的位置,需要hash(A)%2^32
2.用同样的方法将ABC三台服务器映射到环上
3.接下来是映射数据,例如有个a.jpg的图片,那么就通过hash(a.jpg)%2^32映射到环上,并且沿着顺时针查找,第一个遇到的虚拟节点,ABC中的一个,就是需要存放的服务器

那么是不是能解决普通hash的问题呢?
如果这时候加一个服务器D,那么服务器D加入映射到了C和A之间,那么C-D之间的数据本身应该映射到A服务器上,但是由于D的介入,映射到了D服务器上,所以这部分数据失效了,但是其他部分的区域的数据还是照常访问,这就是和hash算法的不同点

一致性hash的小问题

hash倾斜
由于hash算法将节点映射到环上的位置可能出现聚集,也就是不均匀,那么就会导致某一台服务器存放的数据很多,导致负载不均衡,这里能够避免这样的情况发生的方法就是服务器足够多,这样就会均匀分布。但是服务器也是有限资源,要是不够多的情况就可以使用虚拟节点的方法进行扩充填补。

虚拟节点
比如还是刚刚三个服务器ABC,如果C-A之间的区域特别大的话,那么可以在其中添加虚拟节点A1,A2,A3…An,B1,B2,B3…Bn,C1,C2,C3…Cn,这样总体的节点数就会很多,当数据通过hash存放的时候,就可以直接现在找到虚拟节点,然后存放在对应真实节点上就好了,这样就可以弥补C-A之间的数据分布都属于A服务器的缺点了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值