大家好,我是此林。
【浅谈 Redis 主从集群原理(一) 】
上一篇文章中,说到了 Redis 主从复制的全量同步和增量同步,repl_baklog 复制缓冲区,以及 slave 挂掉之后数据同步的措施。
下面介绍的上一篇遗留问题,主节点 master 宕机了,怎么办?
1. 哨兵(Sentinel)
这里贴一张网上的图,对哨兵有个整体了解。
哨兵的作用有三个:
1. 监控:不断地检查 master 和 slave 是否按照预期工作。
2. 自动故障恢复:如果 master 宕机,哨兵会选举一个 slave 提升为 master。
3. 通知:当集群发生故障转移时,会将最新信息推送给 Redis 客户端(如:RedisTemplate)
2. 服务监控
哨兵基于心跳机制监测服务状态,每隔 1 秒向集群的每个实例发送 ping 命令。
- 主观下线:如果某一个哨兵发现有节点没有在规定时间内相应,认为该节点主观下线。
- 客观下线:一般如果超过一半数量的哨兵都认为该节点宕机,那么该节点客观下线。
3. master 选举
如果发现 master 宕机了,需要在 slave 中选举一个作为新的 master。
选举优先级规则:
1. 先根据 slave 和 master 断开时间的长短,剔除掉超过指定阈值的 slave。
2. 然后在剩余的节点中,比较 slave-priority 的大小,越小优先级越高(可以通过配置文件配置)
3. 如果 slave-priority 一样,就比较 slave 的 offset,就是同步进度,越大的代表数据越新。
4. 最后比较 slave 节点的 id 大小,越小优先级越高。
4. 故障转移
当选了一个 slave 作为新的 master 后,开始进行故障转移。
1. 哨兵向新的 master 发送 slaveof no one 命令,让 slave 变成 master。
2. 哨兵再向其他节点发送 slaveof 新master的IP 新master的端口,让其他节点成为新 master 的 slave。
3. 最后,把故障节点标记为 master,这样故障节点恢复后就会成为新 master 的 slave。
5. 哨兵集群搭建
哨兵集群信息如下:
哨兵节点 | IP地址 | 端口号 |
s1 | 192.168.183.128 | 27001 |
s2 | 192.168.183.128 | 27002 |
s3 | 192.168.183.128 | 27003 |
主从集群信息如下:
节点 | IP地址 | 端口号 |
master | 192.168.183.128 | 7001 |
slave1 | 192.168.183.128 | 7002 |
slave2 | 192.168.183.128 | 7003 |
目录信息如下:
在s1、s2、s3目录下创建 sentinel.conf,这是 s1 的。
注:vi 命令编辑,:wq 保存,:q! 不保存退出,键盘按下 i 是insert 模式,\+关键字是搜索
配置解释:
port 27001:指定哨兵端口
sentinel announce-ip :声明当前哨兵的IP地址
sentinel monitor:指定主节点信息。mymaster 是主节点名称,IP 和 端口也是主节点的,2 是当超过两个哨兵认为某个节点主观下线的时候,那么该节点客观下线。
为什么只要配置 master:master 上可以通过 info replication 命令查询到 slave 的信息,所以实际上还是会监控整个集群的。
sentinel down-after-milliseconds:slave 和 master 断开的最大时长
sentinel failover-timeout:slave 故障恢复的超时时间
哨兵启动:
redis-sentinel s1/sentinel.conf
redis-sentinel s2/sentinel.conf
redis-sentinel s3/sentinel.conf
6. RedisTemplate 哨兵模式
RedisTemplate 作为 Redis 的一个客户端,底层利用 lettuce 实现节点的感知和自动切换。
在application.yml 里配置如下:
这里我们发现只要配置哨兵节点即可。
所以总结之前的,可知哨兵有如下作用:
1. 服务监控
2. master 选举和 slave 故障转移
3. 通知 Redis 客户端节点变化
主从读写配置:
@Bean
public LettuceClientConfigurationBuilderCustomizer configurationBuilderCustomizer() {
return configBuilder -> configBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}
这里的 ReadFrom 是配置 Redis 的读取策略:
MASTER:从主节点读取
MASTER_PERFERRED:优先从 MASTER 读取,MASTER 不可用才读取 slave。
REPLICA:从从节点读取
REPLICA_PERFERRED:优先从从节点读取,slave 不可用才读取 MASTER。
主从切换、读写分离、故障转移通知接收由 RedisTemplate 全自动完成,底层已经封装好了,我们无需关注。