Redis——9. 哨兵机制

sentinel初始化

sentinel运作

  • 监控:如何获取主服务器,从服务器,其他哨兵的状态信息
  • 提醒:如何与主从服务器沟通
  • 检测下线状态:当有主服务器下线时,如何检测
  • 自动故障迁移

1.Sentinel启动与初始化

启动命令:

redis-sentinel /path/to/your/sentinel.conf

初始化步骤:

  • 启动服务器,使用sentinel专用代码
  • 初始化SentinelState,建立与主服务器的连接

(1)初始化服务器

具体步骤与服务器初始化差不多,但是少了点步骤,比如不会进行RDB/AOF恢复

(2)使用sentinel专用代码

比如:

1.使用 define REDIS_SENTINEL_PORT 26379 作为端口号

2.命令表不一样,只有一些简单的命令

(3)初始化SentinelState

sentinelState专门记录与哨兵有关的状态

sentinelRedisInstance用来记录每个被监视的服务器的消息,这些服务器可以是主服务器,从服务器,或者其他sentinel。其中比较重要的属性有addr(记录这个服务器的ip+端口号),slaves字典(记录它的从服务器),sentinels(监视它的其他sentinels)

struct sentinelState {

    // 当前纪元,用于实现故障转移
    uint64_t current_epoch;

    // 保存了所有被这个 sentinel 监视的主服务器
    // 字典的键是主服务器的名字
    // 字典的值则是一个指向 sentinelRedisInstance 结构的指针
    dict *masters;

    // 是否进入了 TILT 模式?
    int tilt;

    // 目前正在执行的脚本的数量
    int running_scripts;

    // 进入 TILT 模式的时间
    mstime_t tilt_start_time;

    // 最后一次执行时间处理器的时间
    mstime_t previous_time;

    // 一个 FIFO 队列,包含了所有需要执行的用户脚本
    list *scripts_queue;

} sentinel;
struct sentinelRedisInstance {
    // 标识值,记录了实例的类型,以及该实例的当前状态
    int flags;

    // 实例的名字
    // 主服务器的名字由用户在配置文件中设置
    // 从服务器以及Sentinel的名字由Sentinel自动设置
    // 格式为ip:port
    char *name;

    // 实例的运行ID
    char *runid;

    // 配置纪元,用于实现故障转移
    unit64_t config_epoch;

    // 实例的地址
    sentinelAddr *addr;

    // 实例无响应多少毫秒之后才会被判断为主观下线
    mstime_t down_after_period;

    // 判断这个实例为客观下线所需的支持投票数量
    int quorum;

    // 在执行故障转移操作时,可以同事对行的主服务器进行同步的从服务器数量
    int parallel_syncs;

    // 刷新故障迁移状态的最大时限
    mstime_t failover_timeout;

    // 一个主服务器所有从服务器实例
    dict *slaves;

    // 监视这个主服务器的所有sentinels实例
    dict *sentinels;

    // ...
} sentinelRedisInstance;

(4)连接主服务器

最后一步是创建与主服务器的网络连接。sentinel会创建两个连接:命令连接+订阅连接(__sentinel__:hellp频道)

2.监控

这里监控指:sentinel维护其他主服务器,从服务器,sentinel的状态信息

(1)获取主服务器状态信息

默认每10秒给主服务器发送INFO命令,更新sentinelRedisInstance的信息。

INFO指令返回的信息如下图所示。

(2)获取从服务器状态信息

根据从主服务器那里获取的信息,再对从服务器们创建命令连接和订阅连接,并更新

默认每10秒给从服务器发送INFO命令,获取从服务器信息(如:run_id,角色role,主服务器的ip和端口,连接状态,优先级,偏移量)

(3)获取其他哨兵状态信息

由于Sentinel会用订阅模式给 __sentinel__:hello 频道发信息,每个sentinel收到该信息时:

  • 如果判断出是自己发送的,则忽略
  • 如果是其他sentinel发送的,则将那个sentinel更新到sentinelRedisInstance中

(4)每个主服务器的sentinelRedisInstance如下图所示

3.提醒

这里提醒是指:sentinel向其他发送消息

(1)向主服务器和从服务器发送信息

默认情况下,每2秒发送订阅信息(s_*:自己的信息,m_*:主服务器的信息)

  • 如果发送给主服务器,那么m_*就是它的信息
  • 如果发送给从服务器,那么m_*就是它的主服务器的信息

(2)接受主服务器和从服务器的信息

sentinel订阅了 __sentinel__:hello 频道的信息

4.检测下线状态

检查主观下线(发现某一master可能下线)——> 检查客观下线(询问其他哨兵,确定是否下线) ——> 选举领头

(1)主观下线:自己判断

Sentinel会以每秒1次的频率发送给(从服务器+主服务器+其他哨兵)PING命令。

有效回复为: PONG, LOADING, MASTERDOWN。其他都为无效回复

Sentinel配置文件中的 down-after-milliseconds指定了时间。

eg. sentinel down-after-milliseconds master 50000。

如果master在50秒内都没有进行有效回复,则sentinel认定它已经下线。并把对应的master的flags增加一个标志位 SRI_S_DOWN

(2)客观下线:询问其他

当sentinel主观判断一个主服务器下线后,为了再次确认,会向其他sentinel询问。

2.1 先向其他sentinel发送命令

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
//ip,port为被判断下线的主服务器的ip和port
//current_epoch为配置纪元
//runid:1. * :向其他哨兵检测客观下线
//       2. sentinel的运行id:判断完客观下线后,用于选举领头sentinel

2.2 其他sentinel的回复

<down_state>    //1代表判断主服务器已经下线;0代表未下线
                
<leader_runid>    //*:代表检测下线的回复
                  //runid:用于选举领头哨兵
<leader_epoch>    //当runid=*时:总是为0,无意义
                  //选举时,有效

eg. 
1) 1
2) *
3) 0

这个消息代表其他sentinel也同意服务器下线

2.3 收到其他sentinel的回复

当收到的回复大于一定数量(根据配置信息),该sentinel会认定该主服务器已经客观下线,再增加一个标志位 SRI_O_DOWN

配置: sentinel monitor master 127.0.0.1 6379 5 

表示 >=5个时,就认定已经客观下线

(3)选举领头

当一个sentinel主观客观检测都判断主服务器下线后,会继续发送 is-master-down-by-addr 指令。

不过这次的 runid不再是*, 而是自己的id。

每个sentinel在同一个epoch中只能投一票,对最先收到的那个sentinel进行回复投票,内容如 2.2。

当某个sentinel收到的票数>n/2时(比如,n=10,则需要6票),它将成为领头哨兵

5.故障转移

流程:

(1)挑选新的主服务器

(2)让所有从服务器复制新的主服务器

(3)让原来的主服务器变成从服务器

1.选出新的主服务器

领头sentinel会选出新的主服务器,要求如下

(1)必须在线

(2)响应快的(最近与领头sentinel成功通信过的)

(3)最近与原来的主服务器保持联系的(换句话说,从服务器中保存的数据都是比较新的)

(4)如果有多个满足,则排序:优先级——offset——runid

选出新主服务器后,领头sentinel会给其发送 slaveof no one 命令

发送完后,领头sentinel会以每秒一次给它发送INFO命令,当返回的角色从slave变成master后,就确认成功了

2.修改从服务器的复制目标

给其他从服务器发送 slaveof 命令

3.将旧的主服务器变成从服务器

当旧服务器上线时,向其发送 slaveof 命令

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值