/* ======================== SENTINEL timer handler ========================== * This is the "main" our Sentinel, being sentinel completely non blocking * in design. * -------------------------------------------------------------------------- */
/* Perform scheduled operations for the specified Redis instance. */ voidsentinelHandleRedisInstance(sentinelRedisInstance *ri) { /* ========== MONITORING HALF ============ */ /* Every kind of instance */ // 对于所有检测到的新Instance(包括主、从、哨兵)发起重连 sentinelReconnectInstance(ri); // 发起周期命令,如INFO、PING、HELLO频道 sentinelSendPeriodicCommands(ri);
/* ============== ACTING HALF ============= */ ... /* Every kind of instance */ sentinelCheckSubjectivelyDown(ri); ... /* Only masters */ if (ri->flags & SRI_MASTER) { // 检查是否已经客观下线 sentinelCheckObjectivelyDown(ri); // 如果触发了客观下线,开始状态机流程 if (sentinelStartFailoverIfNeeded(ri)) //立马发一个要求投票的请求 sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_ASK_FORCED); // 状态机主流程 sentinelFailoverStateMachine(ri); // 定期发送is-master-down-by-addr,两个目的 // 1. 获取主观下线的数量 // 2. 重置其他哨兵的投票计时器 sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_NO_FLAGS); } }
/* There are a number of things we need to perform against every master. */ di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { sentinelRedisInstance *ri = dictGetVal(de);
sentinelHandleRedisInstance(ri); if (ri->flags & SRI_MASTER) { sentinelHandleDictOfRedisInstances(ri->slaves); sentinelHandleDictOfRedisInstances(ri->sentinels); if (ri->failover_state == SENTINEL_FAILOVER_STATE_UPDATE_CONFIG) { switch_to_promoted = ri; } } } if (switch_to_promoted) sentinelFailoverSwitchToPromotedSlave(switch_to_promoted); dictReleaseIterator(di); }
/* This function is called when the slave is in * SENTINEL_FAILOVER_STATE_UPDATE_CONFIG state. In this state we need * to remove it from the master table and add the promoted slave instead. */ voidsentinelFailoverSwitchToPromotedSlave(sentinelRedisInstance *master) { sentinelRedisInstance *ref = master->promoted_slave ? master->promoted_slave : master;