哨兵
Redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理方式是无法接受的。为了解决这个问题,Redis提供了Redis Sentinel(哨兵)架构来解决这个问题。
一、基本概念
在做自动故障转移时,需要考虑三个问题:
- 判断主节点不可达的机制是否健全和标准。
- 如果有多个从节点,怎样保证只有一个被晋升为主节点。
- 通知客户端新的主节点机制是否足够健壮
1.1 Redis Sentinel的高可用性
Redis Sentinel是一个分布式架构,其中包含若干个Sentine节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行“协商”,当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。
二、实现原理
2.1 三个定时监控任务
Redis Sentinel通过三个定时监控任务完成对各个节点的发现和监控:
- 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。
- 每隔2秒,每个Sentinel节点会向Redis数据节点的sentinel:hello频道发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息,同时每个Sentinel节点也会订阅该频道,来了解其他Sentinel节点以及它们对主节点的判断,所以这个定时任务可以完成以下两个工作:
- 发现新的Sentinel节点
- Sentinel节点之间交换主节点的状态,作为后面客观下线以及领导者选举的依据。
- 每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点是否可达。
2.2 主观下线和客观下线
主观下线:如2.1中的第三个定时任务介绍,每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过指定时间没做有效回复时,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。主观下线是当前Sentinel节点的一家之言,存在误判的可能。
客观下线:当Sentinel主观下线的节点是主节点时,该Sentinel节点会向其他Sentinel节点询问对主节点的判断,当超过<quorum>个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定。客观下线是大部分Sentinel节点都对主节点做了同意的判定,那么这个判定就是客观的。
注意:从节点、Sentinel节点在主观下线后,没有后续的故障转移操作。如果需要做,可以自己利用Sentinel提供的API实现
2.3 领导者Sentinel节点选举
当Sentinel节点对主节点做了客观下线后,并不是立即进行故障转移,因为可能有其他的Sentinel节点也做了客观下线,这个时候需要选出来一个领导者来做故障转移。
选举思路:Sentinel节点向其他节点发送请求,要求将自己设置为领导者,收到请求的节点如果之前没有同意过其他Sentinel节点的请求,就同意该请求,否则拒绝,最后得票数大于等于max(quorum, num(sentinels) / 2 + 1)的节点被选为领导者。如果没有选出来,就进行下一轮投票。
2.4 故障转移
领导者选举出的Sentinel节点负责故障转移,具体步骤如下:
-
在从节点列表中选出一个新的主节点,选择方法如下:
a. 过滤“不健康”(主观下线、断线)的从节点
b. 选择复制偏移量最大的从节点
-
Sentinel领导者节点会对第一步选出来的机诶单执行slaveof no one命令让其成为主节点
-
Sentinel领导者节点向其余从节点发送命令,让它们成为新主节点的从节点