三,Redis哨兵机制
Redis的哨兵机制主要是为了提高Redis主从模型下的可用性,能保证主节点异常发生时还能够正常的运作并进行故障转移。哨兵机制为了实现这一点提供了以下这些功能:
- 节点监控
- 下线判断
- 领导者选举
- slave选举
- 故障转移
在介绍这些功能前我们先用一张图了解整个Redis哨兵模型
这里的Sentinel便是哨兵集群,他们会监控master节点及其所有的slave节点,实时获取他们的健康信息,根据健康信息的变化来做故障转移。
节点监控
关于哨兵的节点监控的实现是通过三个定时监控任务完成对各个节点的发现和监控的:
Info事件
每隔10s钟就会向当前的master节点发送一个info命令,以获取最新的拓扑结构**。当向主节点执行info命令时,会获取从节点的信息,这也是为什么无需在sentinel配置文件中显示的配置从节点地址。而且有新的节点加入可以立刻感知出来。**
Sentinel节点事件
每隔2s钟就会向 Redis数据节点的__sentinel__:hello
频道向其他Sentienl节点分享自己的主节点信息和自身的Sentinel信息。同时其他Sentinel也会订阅该频道,向了解其他Sentinel节点和他们对主节点的判断,整个过程分为以下两步。
- 发现新的Sentinel节点: 通过订阅主节点的
__sentinel__:hello
频道,了解其他的Sentinel节点信息,如果有新的Sentinel节点加入则会保存他的信息并连接。 - Sentinel之间交换主节点状态: Sentinel之间会交换主节点状态,用于之后的领导者选举。
心跳事件
每隔1s就会向 主节点,从节点,Sentinel节点发送一个心跳感应包。来确保各个节点是否可达
下线判断
对于一个节点的下线分为两个状态:主观下线和客观下线
- 主观下线: 当一个Sentinel节点向某个节点发送心跳包超过
down-after-milliseconds
没有进行有效回复,则该Sentinel认为该节点已经下线
- 客观下线: 当Sentinel下线的是主节点时,会通过
is-master-down-by-addr
的命令向其他Sentinel节点询问主节点的判断,当超过个数时,Sentinel节点则认为主节点确实有问题,此时Sentinel节点会做出客观的下线决定。
sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
ip:主节点
port:主节点端口
current-epoch:当前配置
runid:
当runid为"*"时,代表只是交换主节点下线的判断
当runid为当前sentinelid时,代表希望其他sentinel节点同意他作为leader节点
发送这个命令后,其他sentinel节点会返回如下内容
down_state: 对于主节点的判断是下线还是上线,0和1来进行表示
leader_runid:如果为*代表返回结果是用来做主节点不可达的,如果为具体id则代表同意该id的节点为leader
领导者Sentinel节点选举
因为在后续操作中,需要有一个人能进行slave选举和故障转移,所以必须要选出一个Sentinel节点去做这件事情。Redis使用的是Raft算法来实现领导者选举,Raft算法再次介绍篇幅过长所以就给个大概的思路:
① 每个在线的Sentinel节点都有资格成为Leader,此时发现主节点故障的Sentinel都可以发送一条is-master-down-by-addr
的命令,要求设置自己为领导者。
② 收到该命令的其他Sentinel会查看自己的是否同意过别的Sentinel的leader选举要求,如果没有的话,则将该票投给对应的Sentinel节点,否则不投票拒绝。
③ 如果该Sentinel节点获得的票数大于max(quorum,num(sentinel)/2+1)
,即达到客观下线要求且超过当前sentinel数的一半,则将他选举为领导者
④ 如果选出新的Leader会向其他哨兵通知领导者的消息
⑤ 如果没有选出来,就进行下一轮
所以说如果Sentinel节点发生了宕机并不一定会影响整个系统的可用性,但是如果宕机数超过一半,那么哨兵机制将崩溃无法进行故障转移
slave节点选举
当领导者选出来后,则要让领导者在从库中选择一个新的master节点,那么此时slave节点的选取也是有要求的。
- 过滤: 将不健康的节点,Sentinel无法ping通的节点和与主节点失联超过down-after-milliseconds*10s的节点
- 优先级: 选择slave-pripority最高的节点,存在则返回,不存在则继续
- 同步率最高: 选择offset最大的从节点,说明其复制最完整
- id小节点: 选择id最小的从节点
故障转移
master节点转换: 此时领导者会将选举出来的从节点执行slaveof no one 命令让其成为主节点,并且通知其他的slave节点让他们replicaof新的master节点作为master。
故障节点转换为slave: Sentinel将故障节点转换为slave,当故障节点恢复后自动成为新master节点的slave节点
通知客户端: 通过switch master事件,通知订阅的客户端,当前的集群主节点发生了变化
故障转移失败与failover-timeout
failover-timeout可以理解为故障转移超过时间,当然他实际上和故障转移下面的四个阶段都有深刻联系
① 选举出从节点
② 晋升从节点为主节点
③ 命令其余从节点replicaof主节点
④ 等待原主节点恢复后,命令他去复制新的主节点
1)如果Redis Sentinel对一个主节点故障转移失败,则下一次故障转移起始时间是failover-timeout的2倍
2)在②阶段时,如果Sentinel节点向①阶段选出来的从节点执行 slaveof no one一直失败(例如该从节点此时出现故障),当此过程超过 failover-timeout时,则故障转移失败。
3)在②阶段如果执行成功,Sentinel节点还会执行info命令来确认 a)阶段选出来的节点确实晋升为主节点,如果此过程执行时间超过 failover-timeout时,则故障转移失败。
4)如果③阶段执行时间超过了failover-timeout(不包含复制时 间),则故障转移失败。注意即使超过了这个时间,Sentinel节点也会 最终配置从节点去同步最新的主节点
单哨兵多主从
一个哨兵集群是可以管理多个主从集群的,只需通过如下节点即可实现
sentinel monitor master-business-1 10.10.xx.1 6379 2
sentinel down-after-milliseconds master-business-1 60000
sentinel failover-timeout master-business-1 180000
sentinel parallel-syncs master-business-1 1
sentinel monitor master-business-2 10.16.xx.2 6380 2
sentinel down-after-milliseconds master-business-2 10000
sentinel failover-timeout master-business-2 180000
sentinel parallel-syncs master-business-2 1
优点: 更少的资源使用,更方便的运维管理
缺点: 如果该Sentienl集群失效,会导致其他的主从集群全部丧失高可用性