背景
数据量大 单机无法满足要求 采用多机的解决方案。多机的时候,有个问题,每台机器数据是否同步?
1.同步
所有机器保存的数据一样。比如 jboss cache。
2.不同步
每台机器保存的数据不一样。比如 memcache redis。
不同步,如何找到节点?
即数据写和读,是到同一个节点。2种方法:
1.顺序遍历
2.hash
hash可以分为4种情况,见下文。
顺序遍历
缺点
1.读数据
多个节点 遍历。即遍历访问每一个节点的缓存数据,直到找到数据为止。
hash
优点
解决顺序算法的问题。即hash(object) / 除数,得到一个key,这个key映射到节点,不需要遍历每个节点。流程:
object——》hash(object)/除数——》key——》节点。
分类
1.余数hash
应用场景 数据库分库分表
2.一致性hash
3.一致性hash + 虚拟节点 //优化一致性hash
应用场景 memcache
4.虚拟槽
应用场景 redis
余数hash
原理
hash(object) / 节点数量
缺点
加1或减1 导致余数值改变 而且是所有余数值都改变 //影响所有节点的所有数据
一致性hash
原理
hash(object) / 2~32
和余数hash的2点不同
1.和余数hash的计算方式一样,但是除数更大
2.扩容或缩容的时候,只影响单个节点的数据——因为找节点的时候,是按hash环的顺时针方向找到节点。
优点
解决扩容或缩容的问题。
加1或减1 只影响1个节点的数据 而且是该节点的部分数据 //影响1个节点的部分数据
1)加1 某个节点的部分数据本来指向该节点 现在指向新增的节点
2)减1 某个节点的所有数据本来指向该节点 现在指向该节点的下一个节点
缺点
节点少的时候 数据分布不均匀
一致性hash + 虚拟节点
优点
解决数据落到节点 数据不均匀的问题。
具体解决方法?节点少的时候 哪个节点数据少就加几个虚拟节点 落到虚拟节点的数据全部映射到该节点。
缺点
尽管一致性hash解决了
1.数据分布不均匀
2.扩容或缩容
但是,扩容或缩容仍然会有某个节点的数据失效。
应用场景
memcache
虚拟槽
原理
10000个虚拟节点——》5个槽(1个槽包含2000个虚拟节点)——》5个节点(1个节点对应1个槽)
优点
和一致性hash+虚拟节点一样,要解决的问题都是数据分布到节点的时候 数据不均匀的问题,
1.一致性hash + 虚拟节点
基于hash,外加虚拟节点
2.虚拟槽
也是基于hash,只不过虚拟节点数量足够多 目的就是为了数据分布到节点的时候 数据尽量足够均匀,一般情况下 节点越多 数据分布越均匀。
总结
2个问题
1.节点数据分布不均匀的问题
解决方法 节点越多 数据分布越均匀。
2.增加1个节点或减少1个节点的问题 即扩容或缩容的问题
1)增加1个节点
迁移槽和数据到新的节点。所有的已有节点,每个节点平均迁移一部分槽和数据。
2)减少1个节点
a.迁移槽和数据到其他节点。
b.下线自己,并通知其他节点。
分布式缓存,把数据映射到节点的过程:object——》hash(object)——》key——》节点,不同算法的目的都是为了解决和优化这2个问题,
应用场景
redis
参考
https://zhuanlan.zhihu.com/p/34985026
https://blog.csdn.net/qq_39780174/article/details/78565043