Redis Sentinel Failover判定 源码探寻

前言

Redis sentinel设计初衷是保证Redis服务集群的稳定可用服务。其核心逻辑: 假设有Redis实例采用主从备份机制,如果master机器由于一些原因挂掉不可访问,sentinel可以自动识别出来,并且从master的slaves中选择出一个promote为master,从而保证服务可用。详细文档,参见官网

Failover判定流程

一次failover发生的过程大致如下:
1. sentinel集群(数量为N)中某个实例S发现某个masterM不可访问,则SM标记为sdown(subjectively down)主观下线状态。
2. 当sentinel集群通过交谈(gossip)后,至少有quorum个sentinel认为M不可访问后,将M标记为odown(objectively down)客观下线状态。
3. 处于odown状态后,集群每个sentinel实例投票选举leader主导尝试发起failover流程。
4. 当某个leader得票数超过N/2+1(占多数)时,正式开始failover流程。

备注: 过程3、4官网文档统称为authorize(这个authorize太误导人了,下面详细说)。

源码探究

sentinel是以sentinel模式运行的redis-server。Server.c调用流程如下:
[Server.c]main() ---> initServer() ---> 调用aeCreateTimeEvent注册回调Servercron() ---> 检查sentinel_mode, 调用setSentinelTimer()
Sentinel.c中的涉及到failover判定的主要流程如下:
[Sentinel.c]setSentinelTimer() ---> sentinelHandleDictOfRedisInstances(masters) ---> sentinelHandleRedisInstance()

sentinelHandlerRedisInstance()中:
1. checkSubjectivelyDown()
1. checkOjbectivelyDown()
2. ifNeededFailover()
3. 进入failoverStateMechine
4. askMasterStateToOtherSentinels()

每个sentinel实例都本地维护了一张redisInstance的字典,包括masters、masters->slaves、masters->sentinels,gossip过程中逐步保证字典信息一致性。 例如上述的askMasteStateToOtherSentinels(),从其他sentinel获取master的state,并更新自己的dict。
checkSubjectivelyDown()
checkOjbectivelyDown()这个函数遍历master->sentinels字典, 统计sdown次数,如果>=quorum(这个在配置文件里设置).则置为odown状态。
ifNeededFailover()首先判断满足以下情况时才进行startFailover()过程
1. master处于odown状态
2. 目前master没有正在进行的failover, 即master状态不处于SRI_FAILOVER_IN_PROGRESS
3. 最近没有进行failover, 最近指master->failover_timeout*2, 其中, failover_timeout是从配置文件里面读取的

startfailover()设置master的flag=SRT_FAILOVER_IN_PROGRESS, 获得新epoch, 设置failover_state=SENTINEL_FAILOVER_STATE_WAIT_START

后续, 进入状态机, 总共有5个状态。

SENTINEL_FAILOVER_STATE_WAIT_START
SENTINEL_FAILOVER_STATE_SELECT_SLAVE
SENTINEL_FAILOVER_STATE_SLAVEOF_NOONE
SENTINEL_FAILOVER_STATE_WATI_PROMOTION
SENTINEL_FAILOVER_STATE_RECONF_SLAVES

本文只分析failover判定过程, 即WAIT_STARTSELECT_SLAVE的过程, 调用sentinelFailoverWaitStart(), 主要逻辑:
1. sentinelGetLeader()
2. 如果leader不是自己, abortFailover
3. 设置为SELECT_SLAVE

getLeader()函数中,统计票数最多的一个sentinel。判断满足以下两个条件时, 返回作为leader。
1. 票数>=配置文件里的quorum
2. 票数>=sentinel总数/2 + 1

至此,正式进入failover流程。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值