问题提出
一致性hash是什么?假设有4台缓存服务器N0,N1,N2,N3
,现在需要存储数据OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT5,OBJECT7,OBJECT8
,
我们需要将这些数据缓存到这4台服务器上,相应的问题是
如何设计数据存放策略?即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
上
此时为了保证数据的准确性,我们需要
将数据Object2
从N3
迁移到N0
将数据Object5
从N1
迁移到N2
将数据Object6
从N2
迁移到N0
将数据Object7
从N3
迁移到N1
将数据Object8
从N0
迁移到N2
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
则应该存放到节点N3
上
此时为了保证数据的准确性,我们需要
将数据Object2
从N3
迁移到N0
将数据Object5
从N1
迁移到N0
将数据Object6
从N2
迁移到N1
将数据Object7
从N3
迁移到N2
将数据Object8
从N0
迁移到N3
从上述俩种情况可以看出,一旦机器数目变化,我们面临大量的缓存变化问题,换言之,缓存大部分失效,很可能会导致雪崩。
2.一致性hash方案
现在我们更换如下策略
0N0
2N1
4N2
6N3
2.1 现在假设N3
忽然故障下线
我们面临缓存重新构造的问题,调整策略如下
0N0
2N1
4N2
6N0
此时为了保证数据的准确性,我们需要
将数据ObjectX
从N3
迁移到N0
,受影响的数据仅仅N3相关的数据。
2.2 现在假设我们添加一台新的服务器N4
我们面临缓存重新构造的问题,调整策略如下
0N0
2N1
4N2
5N4
6N3
此时为了保证数据的准确性,我们需要
将数据从N2
复制到N4
,受影响的仅仅N2相关的用户。
比较上述俩种做法,可见方案2更优. 方案2就是一致性hash
2.3 缺点
机器越少,则每台机器上负载将越不均匀,解决这个问题的方法是添加虚拟节点,调整策略,如下,可以想象,数据越多,分布越均匀。
0N0
1N1
2N2
3N3
4N0
5N1
6N2
7N3
3. 一致性Hash原理
原理网络上太多,这里不做进一步阐述。
推荐阅读
扫微信二维码实现网站登陆提供体验地址和源代码
开源项目golang go语言后台管理框架restgo-admin
支持手势触摸,可左右滑动的日历插件
你必须知道的18个互联网业务模型
推荐阅读
扫微信二维码实现网站登陆提供体验地址和源代码
开源项目golang go语言后台管理框架restgo-admin
支持手势触摸,可左右滑动的日历插件
你必须知道的18个互联网业务模型