sentinel无法监控_分布式Redis故障转移(sentinel)

当2台以上Redis实例形成了主备关系,他们组成的集群就具备了一定的高可用:当master 故障时,slave可以成为新的master,对外提供读写服务,这种运行机制称为 failover。那么谁去发现master的故障,并做failover呢?

一种方式是:保持一个daemon进程,监控着所有的master-slave节点,如下所示:

64cc295c6c24f43b0f22b3376b63ca15.png

daemon 进程监控

上图中,一个Redis集群里有一个master和2个slave,并且由daemon进程监控着。这种方式存在的问题是:daemon作为单点,无法保证高可用。因此需要引入更多的daemon,如下所示:

810a7306dd51c25866a702025e97657b.png

多daemon 进程监控

上图中,为了解决daemon单点问题,我们引入了2个daemon进程。但是多个daemon 如何对某个master是否可用达成一致?然后如何决策master是否需要failover?

681c481451dbd217514c740420e57125.png

sentinel 进程监控

上图中,多个daemon 组成的集群称为 sentinel 集群,每个sentinel节点就是daemon节点。这些节点相互通信、选举、协商,在master节点的故障发现、failover决策上表现出一致性。

sentinel 的相互感知

sentinel节点间因为共同监视了同一个master节点,从而也关联了起来。一个新加入的sentinel节点,需要和有相同监视的master的其他sentinel节点相互感知。方式如下:所有需要相互感知的sentinel,都向他们共同的master节点上订阅相同的channel:__sentinel__:hello;新加入的sentinel节点向这个channel发布一条消息,包含了自己的信息,该channel的订阅者们就可以发现这个新的sentinel。随后新的sentinel和已有的其他sentinel建立长连接,如下所示:

622b6295254959b2ef702db83ab480c3.png

sentinel 的相互感知

上图中,新的sentinel加入后,它向master发送加入信息,然后所有订阅的sentinel节点都会感知到新sentinel节点的存在。

三个定时任务

  1. 每10秒,每个Sentinel对master和slave执行info。(发现slave节点;确认主从关系)
  2. 每2秒,每个Sentinel通过master节点的channel交换信息(如上所示:PUB/SUB)。(通过__sentinel__:hello 频道交互;交互对节点的“看法”和自身信息)
  3. 每1秒,每个Sentinel对其他Sentinel和Redis执行ping。

master的故障发现

sentinel节点通过定期的向master发送心跳包判断其存活状态,称为 PING。一旦发现master没有正常的响应,sentinel将此master置为“主观不可用”。所谓“主观”,意思就是还未得到其他sentinel节点的确认,如下所示:

3e107ba69388eaa55a476c508232b292.png

master的故障发现

随后将 “主观不可用” 发送给其他所有的sentinel节点进行确认(is-master-down-by-addr),当确认的 sentinel节点数 >= quorum(可配置)时,则判定该master 为不可用(客观下线),随后进入failover流程。

sentinel monitor 如:sentinel monitor myMaster 127.0.0.1 6379 2sentinel down-after-milliseconds 如:sentinel down-after-milliseconds myMaster 30000

当master主观不可用时,投票的阀值(quorum)是2;确认“主观不可用”的时间阀值是30S。

sentinel Leader 选举

当一台master真正宕机后,可能多个sentinel同时发现了此问题,并通过交互确认“主观不可用”的猜想,然后发起failover。但是最终只能有一个sentinel作为failover的发起者,此时需要开启一个Leader选举的过程,来确定谁来发起failover。

Redis的sentinel机制采用类似 Raft协议 实现这个选举算法:

  1. sentinelState的 Epoch 变量,类似于Raft协议中的term(选举回合)。
  2. 每个确认了master“主观不可用”的sentinel节点,都会向周围广播自己的参选请求。
  3. 每个接收到参选请求的sentinel节点,如果还没人向它发送过参选请求。它就将本选举回合的意向置位首个参选sentinel并回复;如果已经表示过意向了,则拒绝其他的参选,并将自己的意向回复。
  4. 每个发送参选请求的sentinel,如果收到了超过一半的同意意向(投票者包含自己),则确定为Leader;如果本回合持续了足够长的时间还未选出Leader,则开启下一个回合。

Leader sentinel确定之后,从所有master的slave中依据一定的规则,选举出一个新的master,并告知其他slave连接这个master。

故障转移 failover

  1. 从slave节点中选出一个“合适的”节点作为新的master节点;
  2. 对上面的slave节点执行 salveof no one 命令,让其成为master节点;
  3. 向剩余的slave节点发送命令,让它们成为新的master的slave,复制规则和 parallel-syncs 参数有关;
  4. 更新对旧的master节点配置为slave,并保持对其关注,当其恢复后命令其去复制新master节点的内容。

slave 晋升的规则

  1. 选择slave-priority (slave节点优先级)最高的节点,如果存在则返回,不存在则继续;
  2. 选择复制偏移量最大的slave节点(复制最完整的),如果存在则返回,不存在则继续;
  3. 选择 runId 最小的slave节点(最先启动的)。

总结

  • Redis Sentinel 中的 Sentinel节点 数应该>=3,且最好为奇数;
  • Redis Sentinel中的 数据节点 与普通节点没有区别;
  • 客户端初始化连接的是Sentinel节点集合,不再是具体的Redis节点,但Sentinel只是配置中心,不是代理;
  • Redis Sentinel 通过3个定时任务,实现了Sentinel 节点对master、slave和其余Sentinel节点的监控;
  • Redis Sentinel在对节点做失败判定时,分为“主观不可用/主观下线”和“客观不可用/客观下线”;
  • 看懂Redis Sentinel故障转移日志,对于Redis Sentinel以及排查问题非常有帮助;
  • Redis Sentinel实现读写分离高可用,可以依赖Sentinel节点的消息通知,获取Redis数据节点的状态变化。

参考:《深入分布式缓存》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值