主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:
使用分片集群可以解决上述问题,分片集群特征:
- 集群中有多个master,每个master保存不同数据
- 每个master都可以有多个slave节点
- master之间通过ping监测彼此健康状态
- 客户端请求可以访问集群任意节点,最终都会被转发到正确节点?
散列插槽
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到。
数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
- key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
- key中不包含“{}”,整个key都是有效部分
例如:key是num,那么就根据num计算,如果是{id}num,则根据id计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。
故障转移
当集群中有一个master宕机时:
- 首先是该实例与其它实例失去连接
- 然后是疑似宕机?
- 最后是确定下线,自动提升一个slave为新的master
数据迁移
利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。
手动的Failover支持三种不同模式:
- 缺省:默认的流程。
- force:省略了对offset的一致性校验
- takeover:直接标记自己为master,忽略数据一致性、忽略master状态和其它master的意见
RedisTemplate访问分片集群?
RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:
- 引入redis的starter依赖
- 配置分片集群地址
- 配置读写分离
与哨兵模式相比,其中只有分片集群的配置方式略有差异,将哨兵的ip和端口换成了所有主从Redis服务器的ip和端口。
|