Redis设计与实现-12.sentinel

Sentinel(哨兵)是Redis的高可用性的解决方案,由一个或者多个Sentinel实例组成了Sentinel系统可以监视任意多个主服务器,以及这些下属的从服务器。假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程(运行在特殊模式下的Redis服务),它能监控多个master-slave集群,发现master宕机后能进行自懂切换。

它的主要功能有以下几点:

  • 不时地监控redis是否按照预期良好地运行;
  • 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
  • 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。

Sentinel支持集群

很显然,只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:

  • 即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;
  • 如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);
  • 如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。

Sentinel初始化

Sentinel初始化步骤:

  • Sentinel本质上只是一个运行在特殊模式下的Redis服务器,所以初始化Sentinel之前要初始化一个Redis服务器,
  • Sentinel是特殊的服务器,还无法使用Redis的命令以及代码,Sentinel使用自己的专用代码,所以需要将代码换成Sentinel代码。
  • 初始化sentinelState结构
  • 初始化Sentinel状态下的Masters属性
  • 创建连向主服务器的网络连接

服务器会初始化一个sentinel.c/sentinelState结构,这个结构保存了服务器中所有和Sentinel功能有关的状态。

struct sentinelState{
    //当前纪元
    unit64_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;
  • 命令连接:这个连接专门用于向主服务器发送命令,并接收命令回复。
  • 订阅连接:专门订阅主服务器的 _sentinel_:hello频道。

Sentinel的三个定时任务

1.Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器和从服务器发送INFO命令,并通过分析INFO命令的回复来获取服务器的当前信息。

2.每2秒每个sentinel节点通过master节点的channel(sentinel:hello)交换信息

 

 3.每1秒每个sentintel节点对master节点和slave节点以及其余的sentinel节点执行ping操作

 Sentinel的主观客观下线

主观下线:当前Sentinel节点认为Redis节点不可用

客观下线:当前Sentinel接收到其他Sentinel消息,认定这个Redis节点不可用。(执行故障转移)

Sentinel故障转移

 

 

 Sentinel的选举

1. 领导者选举

作用:选举出一个sentenel节点作为领导者去进行故障转移操作。

过程:

1). 每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。

2). 收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。

3). 如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者。

4). 如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。

2. 选出新的master节点

redis sentinel会选一个合适的slave来升级为master,那么,如何选择一个合适的slave呢?顺序如下:

1). 选择slave-priority最高的slave节点(默认是相同)。

2). 选择复制偏移量最大的节点。

3). 如果以上两个条件都不满足,选runId最小的(启动最早的)。

3. 更改slave节点的master节点

当选举出新的master节点后,会将其余的节点变更为新的master节点的slave节点,如果原有的master节点重新上线,成为新的master节点的slave节点。

4. 通知客户端

当所有节点配置结束后,sentinel会通知客户端节点变更信息。

5. 客户端连接新的master节点

客户端收到节点信息后,会连接新的master节点。

posted @ 2020-05-02 14:23  名字可以起这么长  阅读(217)  评论(0编辑  收藏  举报