1

顺风车运营研发团队 周生政

哨兵的配置与启动
启动命令

redis-server --sential  /path/to/your/sential.conf
redis-sential /path/to/your/sential.conf

配置文件sential.conf

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
 
sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5

Redis 哨兵的服务框架

int main(int argc, char **argv) {
    // 通过命令行参数确认是否启动哨兵模式
    server.sentinel_mode = checkForSentinelMode(argc,argv);
    // 初始化服务器配置,主要是填充redisServer 结构体中的各种参数
    initServerConfig();
    // 将服务器配置为哨兵模式,与普通的redis 服务器不同
    if (server.sentinel_mode) {
        // initSentinelConfig() 只指定哨兵服务器的端口
        initSentinelConfig();
        //替换哨兵特有命令
        initSentinel();
    }
    //加载配置文件,
    loadServerConfig(configfile,options);
 
 
    // 检测哨兵模式是否正常配置
    sentinelIsRunning();
     
    // 进入事件循环
    aeMain(server.el);
    // 去除事件循环系统
    aeDeleteEventLoop(server.el);
    return 0;
}

哨兵结构体
哨兵监控对象结构体
master,slave,其他哨兵

typedef struct sentinelRedisInstance {
     .....
    /* Master独有 */                                                                                                     
      dict *sentinels;    /* Other sentinels monitoring the same master. */
      dict *slaves;       /* Slaves for this master instance. */
 
}sentinelRedisInstance

哨兵结构体

struct sentinelState {
      dict *masters;      /* Dictionary of master sentinelRedisInstances.
                             Key is the instance name, value is the
                             sentinelRedisInstance structure pointer. */
  } sentinel;

哨兵结构体关系

clipboard.png

哨兵监控流程

void sentinelHandleRedisInstance(sentinelRedisInstance *ri) {
      //链接监控的服务器,发送ping,并订阅hello频道
      sentinelReconnectInstance(ri);
      //执行各种周期性命令
      sentinelSendPeriodicCommands(ri);
}

哨兵周期性命令

  • 向master和slaves发送info命令
  • 向master、slaves、sentinel发送ping命令
  • 向master、slaves、sentinel发送hello 消息
  • 检查master、slaves、sentinel的主观下线
  • 对master检查客观下线,并进行故障转移

execv和fork
为了做两件事,可以fork出两个进程,替换子进程做其他事情

fork() 复制当前进程, 子进程返回 0 , 父进程返回子进程的pid
fork() 返回-1标识失败
通常 fork/exec 对 替换子进程

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
 
int main(int argc, char **argv)
{
    pid_t i = fork();
    if (i == 0)
    {
        execv("./prcs1", (char *[]){ "./prcs1", argv[1], NULL });
        _exit(1);
    }
    else if (i > 0)
    {
        execv("./prcs2", (char *[]){ "./prcs2", argv[0], NULL });
        _exit(2);
    }
    else
    {
        perror("fork failed");
        _exit(3);
    }
}

AI及LNMPRG研究
7.2k 声望12.8k 粉丝

一群热爱代码的人 研究Nginx PHP Redis Memcache Beanstalk 等源码 以及一群热爱前端的人