调用链: serverCron -> sentinelTimer -> sentinelHandleDictOfRedisInstances -> sentinelHandleRedisInstance
重要函数
这里只是给出表格,下面几节会具体分析
名称 | 功能 |
---|---|
sentinelTimer | 由serverCron中定时调用,遍历本机(sentinel)监视的所有主服务器; |
sentinelHandleRedisInstance | 处理一个单独实例,实现了主要逻辑; |
sentinelReconnectInstance | Monitor half之一;建立连接(cc、pc); |
sentinelSendPeriodicCommands | Monitor half之一;对实例进行定期操作:INFO(10s), PUBLISH (2s), PING(1s) |
sentinelCheckSubjectivelyDown | 及以下都是Acting half;本机判断一个实例是否主观下线; |
sentinelCheckObjectivelyDown | 本机判断一个主服务器(不是实例)是否客观下线 |
sentinelStartFailoverIfNeeded | 发送SENTINEL is-master-down,但依据状态,会执行不同功能,之后详解; |
sentinelFailoverStateMachine | 故障转移状态机; |
以Sentinel模式启动的redis服务器,会在init*Config等函数中以Sentinel模式专用代码替换普通redis服务器的代码,这里不细说。在serverCron定时函数中,服务器调用sentinelTimer,后者会遍历本机(sentinel)监视的所有主服务器代表的实例(sentinelInstance)。
void sentinelTimer(void) { /* 判断是否处于Tilt模式(一种保护模式,当计算机时间发生剧烈变化时发生) */ sentinelCheckTiltCondition(); /* 处理sentinel中的所有sentinelInstance */ sentinelHandleDictOfRedisInstances(sentinel.masters); // ... }
void sentinelHandleDictOfRedisInstances(dict *instances) { dictIterator *di; dictEntry *de; sentinelRedisInstance *switch_to_promoted = NULL; /* There are a number of things we need to perform against every master. */ /* sentinelInstance,可以是master,slave或sentinel */ di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { sentinelRedisInstance *ri = dictGetVal(de); /* 处理当前实例 */ sentinelHandleRedisInstance(ri); if (ri->flags & SRI_MASTER) { /* 如果实例是master,递归处理它的slave和sentinels */ 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); }