关于一致性hash,这多是全网最形象生动最容易理解的文档,想作架构师的你来了解一下

问题提出

一致性hash是什么?假设有4台缓存服务器N0,N1,N2,N3,如今须要存储数据OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT5,OBJECT7,OBJECT8,
咱们须要将这些数据缓存到这4台服务器上,相应的问题是golang

如何设计数据存放策略?即ObjectX 应该存放在哪台服务器上?

为了解决这个问题,咱们有以下几个思路。缓存

1. 余数hash方案

采用hash(Objectx)%4来肯定服务器节点

假设 hash(OBJECT1)=2,由 2%4=2,可知,Object1则应该存放到节点N2
假设 hash(OBJECT2)=3,由 3%4=3,可知,Object2则应该存放到节点N3
假设 hash(OBJECT3)=1,由 1%4=1,可知,Object3则应该存放到节点N1
假设 hash(OBJECT4)=0,由 1%4=1,可知,Object4则应该存放到节点N0
假设 hash(OBJECT5)=5,由 5%4=1,可知,Object5则应该存放到节点N1
假设 hash(OBJECT6)=6,由 6%4=2,可知,Object6则应该存放到节点N2
假设 hash(OBJECT7)=7,由 7%4=3,可知,Object7则应该存放到节点N3
假设 hash(OBJECT8)=8,由 8%4=0,可知,Object8则应该存放到节点N0服务器

假设咱们须要读取Object3的数据,则由hash(object3)=1可知,咱们只须要访问节点N1便可。微信

1.1 如今假设N3突然故障下线

咱们面临缓存从新构造的问题网络

采用hash(Objectx)%3来肯定服务器节点

假设 hash(OBJECT1)=2,由 2%3=2,可知,Object1则应该存放到节点N2
假设 hash(OBJECT2)=3,由 3%3=0,可知,Object2则应该存放到节点N0
假设 hash(OBJECT3)=1,由 1%3=1,可知,Object3则应该存放到节点N1
假设 hash(OBJECT4)=0,由 0%3=0,可知,Object4则应该存放到节点N0
假设 hash(OBJECT5)=5,由 5%3=2,可知,Object5则应该存放到节点N2
假设 hash(OBJECT6)=6,由 6%3=0,可知,Object6则应该存放到节点N0
假设 hash(OBJECT7)=7,由 7%3=1,可知,Object7则应该存放到节点N1
假设 hash(OBJECT8)=8,由 8%3=2,可知,Object8则应该存放到节点N2框架

此时为了保证数据的准确性,咱们须要
将数据Object2N3迁移到N0
将数据Object5N1迁移到N2
将数据Object6N2迁移到N0
将数据Object7N3迁移到N1
将数据Object8N0迁移到N2ide

1.2 如今假设咱们添加一台新的服务器N4

咱们面临缓存从新构造的问题网站

采用hash(Objectx)%5来肯定服务器节点

假设 hash(OBJECT1)=2,由 2%5=2,可知,Object1则应该存放到节点N2
假设 hash(OBJECT2)=3,由 3%5=3,可知,Object2则应该存放到节点N3
假设 hash(OBJECT3)=1,由 1%5=1,可知,Object3则应该存放到节点N1
假设 hash(OBJECT4)=0,由 0%5=0,可知,Object4则应该存放到节点N0
假设 hash(OBJECT5)=5,由 5%5=0,可知,Object5则应该存放到节点N0
假设 hash(OBJECT6)=6,由 6%5=1,可知,Object6则应该存放到节点N1
假设 hash(OBJECT7)=7,由 7%5=2,可知,Object7则应该存放到节点N2
假设 hash(OBJECT8)=8,由 8%5=3,可知,Object8则应该存放到节点N3idea

此时为了保证数据的准确性,咱们须要插件

将数据Object2N3迁移到N0
将数据Object5N1迁移到N0
将数据Object6N2迁移到N1
将数据Object7N3迁移到N2
将数据Object8N0迁移到N3

从上述俩种状况能够看出,一旦机器数目变化,咱们面临大量的缓存变化问题,换言之,缓存大部分失效,极可能会致使雪崩。

2.一致性hash方案

如今咱们更换以下策略

0<hash(Objectx)%8<=2 ,则存放在 N0
2<hash(Objectx)%8<=4 ,则存放在 N1
4<hash(Objectx)%8<=6 ,则存放在 N2
6<hash(Objectx)%8<=8 ,则存放在 N3

2.1 如今假设N3突然故障下线

咱们面临缓存从新构造的问题,调整策略以下

0<hash(Objectx)%8<=2 ,则存放在 N0
2<hash(Objectx)%8<=4 ,则存放在 N1
4<hash(Objectx)%8<=6 ,则存放在 N2
6<hash(Objectx)%8<=8 ,则存放在 N0

此时为了保证数据的准确性,咱们须要
将数据ObjectXN3迁移到N0,受影响的数据仅仅N3相关的数据。

2.2 如今假设咱们添加一台新的服务器N4

咱们面临缓存从新构造的问题,调整策略以下

0<hash(Objectx)%8<=2 ,则存放在 N0
2<hash(Objectx)%8<=4 ,则存放在 N1
4<hash(Objectx)%8<=5 ,则存放在 N2
5<hash(Objectx)%8<=6 ,则存放在 N4
6<hash(Objectx)%8<=8 ,则存放在 N3

此时为了保证数据的准确性,咱们须要
将数据从N2复制到N4,受影响的仅仅N2相关的用户。

比较上述俩种作法,可见方案2更优. 方案2就是一致性hash

2.3 缺点

机器越少,则每台机器上负载将越不均匀,解决这个问题的方法是添加虚拟节点,调整策略,以下,能够想象,数据越多,分布越均匀。

0<hash(Objectx)%8<=1 ,则存放在 N0
1<hash(Objectx)%8<=2 ,则存放在 N1
2<hash(Objectx)%8<=3 ,则存放在 N2
3<hash(Objectx)%8<=4 ,则存放在 N3
4<hash(Objectx)%8<=5 ,则存放在 N0
5<hash(Objectx)%8<=6 ,则存放在 N1
6<hash(Objectx)%8<=7 ,则存放在 N2
7<hash(Objectx)%8<=8 ,则存放在 N3

3. 一致性Hash原理

原理网络上太多,这里不作进一步阐述。

推荐阅读

扫微信二维码实现网站登录提供体验地址和源代码

开源项目golang go语言后台管理框架restgo-admin

支持手势触摸,可左右滑动的日历插件

你必须知道的18个互联网业务模型

推荐阅读
扫微信二维码实现网站登录提供体验地址和源代码
开源项目golang go语言后台管理框架restgo-admin
支持手势触摸,可左右滑动的日历插件
你必须知道的18个互联网业务模型

相关文章
相关标签/搜索