哨兵模式 Sentinel
sentinel 简介
- 手动故障转移、2. 写能力和存储能力受限,其他节点只是主节点的副本
redis sentinel 分为几个节点,相当于redis的进程,不会存储数据,作用是完成redis的故障判断和故障转移,并且通知客户端的过程。
Sentinel其实是一个redis的服务端程序,会定时执行一些serverCron函数来获取整个集群模式下的信息,可以在无需人工干预的情况下做到故障转移。Sentinel
是一个分布式系统,也就是说Sentinel
本身也是可以做集群的。
Sentinel的作用是用来故障发现,故障自动转移,并且通知客户端的过程。(监控和故障转移的通知)
其中,一套sentinel可以监控多套redis的master和slave,使用master-name标识进行监控
redis sentinel 故障转移的过程步骤原理:
- 多个sentinel发现并确认master有问题,将连接进行中断
- 选举出一个sentinel作为领导
- 选出一个slave作为master
- 通知其余slave称为新的master的slave
- 通知客户端主从变化
- 如果原有的master复活了,则等待老的master复活成为新master的slave
redis sentinel的安装和配置
-
配置开启主从节点
-
配置开启sentinel监控主节点(sentinel是特殊的redis)
-
实际应该多机器
-
详细配置节点
监控机制
Sentinel具有故障转移能力,则我们必须知道redis主、从服务器运行时的信息(ip、端口号、状态等),sentinel通过三个定时监控任务完成对各个节点发现和监控。
-
主从节点信息监控
每隔10
秒执行info,每个Sentinel
节点会向主节点和从节点发送info
命令获取最新的拓扑结构。如下图(忽略psync
,这个是主从复制的时候触发):
作用
- 通过向主节点执行
info
命令,获取从节点的信息,这也是为什么Sentinel
节点不需要显式配置监控从节点。 - 当有新的从节点加入时都可以立刻感知出来。
- 节点不可达或者故障转移后,可以通过
info
命令实时更新节点拓扑信息。
-
对主节点监控
每隔2
秒,每个Sentinel
节点会向 Redis 主节点的__sentinel__:hello
频道上发送该Sentinel
节点对于主节点的判断以及当前Sentinel
节点的信息,同时每个Sentinel
节点也会订阅该频道,来了解其他Sentinel
节点以及它们对主节点的判断。
作用
- 通过订阅主节点的
__sentinel__:hello
了解其他的Sentinel
节点信息,如果是新加入的Sentinel
节点将该Sentinel
节点信息保存起来,并与该Sentinel
节点创建连接。 Sentinel
节点之间交换主节点的状态,作为后面客观下线(这个后面会说)以及领导者选举的依据。
-
心跳检测
每隔1
秒,每个Sentinel
节点会向主节点
、从节点
、其余Sentinel节点
发送一条ping
命令做一次心跳检测,来确认这些节点当前是否可达。这个定时任务是节点失败判定的重要依据。
三个定时任务 | 每10秒每个sentinel对master和slave执行info | 每2秒每个sentinel通过master节点的channel交换信息(pub/sub) | 每1秒每个sentinel对其他sentinel和redis执行ping(心跳检测) |
---|
| 发现slave节点 | 通过_sentinel_:hello 频道交互 | 心跳检测,失败判定依据 |
| 确定主从关系 | 交互对节点的“看法”和自身信息 | |
| | | |
主观和客观下线
sentinel monitor # 建议quorum为 节点数/2 + 1 ,并且建议为奇数
sentinel monitor myMaster 127.0.0.1 6379 2
sentinel down-after-milliseconds
sentinel down-after-milliseconds myMaster 30000
主观下线:每个sentinel节点对redis节点失败的偏见
客观下线:所有sentinel节点对redis节点失败"达成共识"(超过quprum个通过)
sentinel is-master-down-by-addr :问一下其他的sentinel节点,是否你们也认为当前这个master节点是需要做一个客观下线的(slave做一个主观下线就好了)
-
主观下线
定时任务中有提到Sentinel
节点会每隔1
秒对主节点
、从节点
、其他Sentinel节点
发送ping
命令做心跳检测,当这些节点超过down-after-milliseconds
(配置文件中的属性)没有进行有效回复,Sentinel
节点就会对该节点做失败判定,这个行为叫做主观下线(站在一个Sentinel
的角度上,当前Sentinel
认为下线就是主观)。
-
客观下线
当Sentinel
主观下线的节点是主节点时,该 Sentinel 节点会通过sentinel is-master-down-by-addr
命令向其他Sentinel
节点询问对主节点的判断,当超过quorum
个数,Sentinel
节点认为主节点确实有问题,这时该Sentinel
节点会做出客观下线的决定,这样客观下线的含义是比较明显了,也就是大部分Sentinel
节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。
Sentinel选举
当sentinel客观判定认为主节点下线后,是不会立即执行redis的故障转移,因为执行故障转移只需要一个sentinel来操作,那该由哪一个sentinel来执行呢?这个时候回出现一个选举leader的过程
sentinel选举过程:
- 每个在线的
Sentinel
节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel
节点发送sentinel is-master-down-by-addr
命令,要求将自己设置为领导者。 - 收到命令的
Sentinel
节点,如果没有同意过其他Sentinel
节点的sentinelis-master-down-by-addr
命令,将同意该请求,否则拒绝。 - 如果该
Sentinel
节点发现自己的票数已经大于等于num / 2 + 1
(num
为Sentinel
节点个数),那么它将成为领导者。 - 如果此过程没有选举出
Leader
,将进入下一次选举。
故障转移
Sentinel
的作用就是用来做故障转移的。现在Sentinel
客观下线了主节点,上面也把Sentinel
的Leader
选举出来了,最后的步骤就是通过这个Leader
来操作故障转移。
大概过程如下:
- 选择合适的从节点 因为整个集群环境存在多个从节点,所以
Sentinel
在操作故障转移过程时会有一个过滤从节点的过程,选择合适的一台从节点提升为主节点,步骤如下:
1.1 过滤掉主观下线、5
秒内没有回复过Sentinel
节点ping
响应、与主节点失联超过down-after-milliseconds*10
秒的从节点。
1.2 选择slave-priority
(从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
1.3 选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续。
1.4 选择runid
最小的从节点。 Sentinel
领导者节点会对第一步选出来的从节点执行slaveof no one
命令让其成为主节点。Sentinel
领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点,复制规则和parallel-syncs
参数有关。Sentinel
节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点。
Sentinel的局限性
-
部署麻烦、原理复杂、浪费资源,从节点作为备份节点不提供服务。
-
不支持读写分离,实现起来相对复杂。
-
只支持对主节点的故障转移,不支持对从节点的故障转移。
-
存储的数据量有限,因为Sentinel
的基础是主从复制,所有主节点和从几点都包含了 Redis 全量的数据。
总结
主要把上面的监控机制、Sentinel
的Leader
选举、故障转移概念和流程搞清楚问题就不大。
参考:慕课课程(Redis从入门到高可用 分布式实践)