sentinel 模式以100ms(理想情况下)的速度调用sentinelTimer
1、 执行sentinelCheckTiltCondition判断是否进入tilt模式
检查当前之间与sentinel.previous_time的时间差值,如果为负值或者大于阀值进入tilt模式,进入tilt模式会发送消息到+tilt频道
2、 执行sentinelHandleDictOfRedisInstances函数
对master执行sentinelHandleRedisInstance
i. 尝试重连如果断开连接的话
ii. 发送周期性命令
10000ms发送一个info命令
a) 异步回复处理策略
i. 判断runnid,更新该master的runnid如果现在ri->runnid = NULL, 如果非NULL, 会比较两次runnid是否一致,如果不一致认为master重启过了,将发送消息到+reboot频道通知该master重启了
ii.
down_after_period小于1000ms,则在down_after_period时间内发送一个ping命令,否则以1000ms为周期发送
a) 异步回复处理
i. 根据回复修改last_avail_time、last_ping_time 和last_pong_time
当回复PONG、LOADING、MASTERDOWN时,last_avail_time设置为当前时间,last_ping_time设置为0
Last_pong_time 设置为当前时间
大于2000ms发送一个hello
a) 异步回复处理
i. 修改上次pub时间last_pub_time
iii. 检验tilt模式
当当前时间减去sentinel.tilt_start_time 大于30个ping周期,一共30s时,取消tilt模式,并发送消息到频道-tilt中
iv. 检查master是否主观下线
检验命令线路:当前时间- 命令连接创建时间,并且未收到ok(状态为PONG,LOADING,MASTERDOWN)的ping回复,并且当前时间-last_ping_time 大于 down_after_period/2 ,并且当前时间-last_pong_time 大于 down_after_perod/2。断开连接
检验pubsub线路:当前时间-pubsub链路建立时间大于最小重连周期15s,并且当前时间-上一次收到消息是3倍的publish周期,则kill掉连接
如果last_ping_time 不等于0(不等于0表示收到的ping回复不是PONG,LOADDING,MASTERDOWN的任意一种),并且当前时间-last_ping_time的差值大于down_after_peroid并且role_reported为slave,当前时间减去role_reported_time 大于down_after_peroid+2倍的info命令周期,设为主观下线,并发送消息到+sdown频道,否则取消主观下线,发送消息到-sdown频道(即master重新活起来了)
v. 检查master是否客观下线
首先它得是主观下线状态,如果不是主观下线状态取消客观下线,并发消息到-odown频道。
如果sentinel认为该master是主观下线,那么计算该master下面的sentinel认为该master是主观下线的个数,如果个数大于该master的quorum,则认为是客观下线,并发送消息到+odown频道
vi. 是否需要故障转移
前提必须是已经是客观下线状态
如果当前时间与上一次尝试故障转移的时间的差值小于该master的failover_timeout的2倍,写日志,return
如果不是以上的两种情况,开始故障转移
a) 设置该master的failover_state 为SENTINEL_FAILOVER_STATE_WAIT_START
b) 设置该master的flag为SRI_FAILOVER_IN_PROGRESS
c) 发送sentinel is-master-down-by-addr 命令自荐为局部领头sentinel
i. 先到者先得或者请求者纪元大于被请求者的局部领导纪元,请求者将设为被请求者的局部领头sentinel。
ii. 请求者收被请求者的应答后更新自己的为响应信息中指定的局部领头(可能是自己也可能是被请求者原来的局部领头sentinel,两者达成一致)
iii. 统计局部领头sentinel的得票数,超过一般为领头sentinel
领头sentinel进入SENTINEL_FAILOVER_STATE_SELECT_SLAVE状态
i. 找出有效的slave
slave不能是SRI_S_DOWN|SRI_O_DOWN|SRI_DISCONNECTED的任意一个
slave->slave_priority 不能为0
slave->last_avail_time不能大于5个sentinel ping 周期即5s
slave->info_refresh时间必须是在3个sentinel info时间周期内,即30s
slave->master_link_down_time 不能大于(现在的时间-减去主观down的时间+10个down_after_prioid
ii. 对有效的slave进行快速排序,对比slave的priority
iii. 第一个为推荐的slave
iv. 如果没有找到推荐的slave,清除failover标记,重新尝试
进入SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE
i. 发送slaveof no one 命令给推荐的slave,使得其进入完成slave到master的转换
进入SENTINEL_FAILOVER_STATE_WAIT_PROMOTION状态
i. 等待slave完成转换,检查当前时间与刚进入该状态的时间差值,当这个差值超过failover_time时,重置failover状态,重新尝试
ii. 通过向slave发送info命令,发现该slave的role变为master,说明完成slave到master的转换,进入SENTINEL_FAILOVER_STATE_RECONF_SLAVES状态
进入SENTINEL_FAILOVER_STATE_RECONF_SLAVES状态
i. 给slave发送slave of promoted_slave’s ip prmmoted_slave’s port完成其他slave的master为新的master
ii. 检查所有的slave状态是否完成指向新的master,所有以完成,这些状态信息来自于法案送info消息给slave,进入SENTINEL_FAILOVER_STATE_UPDATE_CONFIG状态。
进入SENTINEL_FAILOVER_STATE_UPDATE_CONFIG状态
重置信息
来源:oschina
链接:https://my.oschina.net/u/1380836/blog/646340