存储能力问题
主从和哨兵可以解决高可用、高并发读的问题。但是存在两个问题:
- 海量数据存储问题
- 高并发写问题
使用分片集群可以解决上述问题:
- 集群中有多个master,每个master保存不同数据
- 每个master都可以有多个slave节点
- master之间通过ping检测彼此健康状态
- 客户端请求可以访问集群任意节点,最终都会被发到正确节点
散列插槽
redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:
数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
- key中包含{},且其中至少1个字符,{}中的部分是有效部分
- key中不包含{},整个key都是有效部分
redis如何判断某个key应该在哪个实例:
- 将16384个插槽分配到不同的实例
- 根据key的有效部分计算哈希值,对16384取余
- 余数作为插槽,寻找插槽所在实例
如何将同一类数据固定的保存在同一个redis实例:
- 这一类数据使用相同的有效部分,例如key都以{typeid}为前缀
集群伸缩
查看帮助文档
故障转移
当集群中有一个master宕机会发生什么
- 首先是该实例失去连接
- 然后是疑似宕机
- 最后是确定下线,自动提成一个slave为新的master
手动故障转移:
利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移,流程:
- slave节点告诉master节点拒绝任何客户端请求
- master返回当前的数据offset给slave
- 等待offset与master一致
- 开始故障转移
- 标记自己为master,广播故障转移的结果
手动的failover支持三种不同模式:
- 缺省:默认流程,如上
- force:省略对offset的一致性校验
- takeover:直接执行第五步,忽略数据一致性、忽略master状态和其他master的意见
RedisTemplate访问分片集群
方式与哨兵基本一致:
- 引入redis的starter依赖
- 配置分片集群地址(所有)
- 配置读写分离