博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试再被问到一致性 Hash 算法,这样回答面试官!
阅读量:3920 次
发布时间:2019-05-23

本文共 1070 字,大约阅读时间需要 3 分钟。

 公众号后台回复“学习”,免费获取精品学习资料

扫描下方海报 试听

本文来自会点代码的大叔的投稿

01

数据分片

✔︎ 先让我们看一个例子吧

我们经常会用 Redis 做缓存,把一些数据放在上面,以减少数据的压力。

当数据量少,访问压力不大的时候,通常一台Redis就能搞定,为了高可用,弄个主从也就足够了;

当数据量变大,并发量也增加的时候,把全部的缓存数据放在一台机器上就有些吃力了,毕竟一台机器的资源是有限的

通常我们会搭建集群环境,让数据尽量平均的放到每一台 Redis 中,比如我们的集群中有 4 台Redis。

那么如何把数据尽量平均地放到这 4 台Redis中呢?最简单的就是取模算法:

hash( key ) % N,N 为 Redis 的数量,在这里 N = 4 ;

看起来非常得美好,因为依靠这样的方法,我们可以让数据平均存储到 4 台 Redis 中,当有新的请求过来的时候,我们也可以定位数据会在哪台 Redis 中,这样可以精确地查询到缓存数据。

02

数据分片会遇到的问题

但是 4 台 Redis 不够了,需要再增加 4 台 Redis ;那么这个求余算法就会变成:hash( key ) % 8 ;

那么可以想象一下,当前大部分缓存的位置都会是错误的,极端情况下,就会造成 缓存雪崩。

03

一致性 Hash 算法

一致性 Hash 算法可以很好地解决这个问题,它的大概过程是这样的:

把 0 作为起点,2^32-1 作为终点,画一条直线,再把起点和终点重合,直线变成一个圆,方向是顺时针从小到大。0 的右侧第一个点是 1 ,然后是 2 ,以此类推。

对三台服务器的 IP 或其他关键字进行 hash 后对 2^32 取模,这样势必能落在这个圈上的某个位置,记为 Node1、Node2、Node3。

然后对数据 key 进行相同的操作,势必也会落在圈上的某个位置;然后顺时针行走,可以找到某一个 Node,这就是这个 key 要储存的服务器。

如果增加一台服务器或者删除一台服务器,只会影响 部分数据。

但如果节点太少或分布不均匀的时候,容易造成 数据倾斜,也就是大部分数据会集中在某一台服务器上。

为了解决数据倾斜问题,一致性 Hash 算法提出了【虚拟节点】,会对每一个服务节点计算多个哈希,然后放到圈上的不同位置。

当然我们也可以发现,一致性 Hash 算法,也只是解决大部分数据的问题。

END

如有收获,请划至底部,点击“在看”,谢

欢迎长按下图关注公众号石杉的架构笔记

BAT架构经验倾囊相授

转载地址:http://goern.baihongyu.com/

你可能感兴趣的文章
模式18.桥接模式-Java
查看>>
模式21.中介者模式-Java
查看>>
剑指 Offer 46. 把数字翻译成字符串
查看>>
剑指 Offer 48. 最长不含重复字符的子字符串
查看>>
剑指 Offer 49. 丑数
查看>>
剑指 Offer 50. 第一个只出现一次的字符
查看>>
模式23.解释器模式-Java
查看>>
模式22.享元模式-Java
查看>>
剑指 Offer 52. 两个链表的第一个公共节点
查看>>
剑指 Offer 53 - I. 在排序数组中查找数字 I
查看>>
剑指 Offer 53 - II. 0~n-1中缺失的数字
查看>>
剑指 Offer 54. 二叉搜索树的第k大节点
查看>>
剑指 Offer 55 - I. 二叉树的深度
查看>>
剑指 Offer 55 - II. 平衡二叉树
查看>>
剑指 Offer 56 - I. 数组中数字出现的次数
查看>>
模式24.访问者模式-Java
查看>>
剑指 Offer 56 - II. 数组中数字出现的次数 II
查看>>
剑指 Offer 57. 和为s的两个数字
查看>>
剑指 Offer 57 - II. 和为s的连续正数序列
查看>>
剑指 Offer 58 - I. 翻转单词顺序
查看>>