Redis源码分析Sentinel(1)Sentinel服务器

一、概述:

调用链: 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功能?:

​ 以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);
}
  • L12:sentinelHandleRedisInstance用来处理所有实例,它分为负责建立连接(cc、pc)和处理周期任务(INFO、PUBLISH、PING)的Monitor half,和负责处理逻辑的Acting half,sentinel部分的第三篇文章将介绍Monitor half,第四篇介绍Acting half。
  • L15~16:主服务器的实例对象保存了两个字典,分别保存从服务器和所有监视它的Sentinel。所以本机遍历处理主服务器时,同样会递归处理这些从服务器和Sentinel。
原文地址:https://www.cnblogs.com/macguz/p/15865706.html