zoukankan      html  css  js  c++  java
  • 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。
  • 相关阅读:
    C#中class的访问级别
    Install-Package 那点事儿
    Gherkin学习笔记
    mysql-connector-c 安装
    shell实现死循环
    每天一个小算法(6)---- 通过两个栈实现一个队列
    每天一个小算法(5)----找到链表倒数第K个结点
    每天一个小算法(4)----在O(1)时间删除指定结点
    每天一个小算法(3)----倒序打印链表
    每天一个小算法(2)----合并两个有序链表
  • 原文地址:https://www.cnblogs.com/macguz/p/15865706.html
Copyright © 2011-2022 走看看