Sentinel哨兵机制实现Redis的高可用

版权声明:非商业目的可自由转载,转载请标明出处 https://blog.csdn.net/u010013573/article/details/88243663

概述

  • Sentinel哨兵机制是Redis的高可用的解决方案,如名字一样,该机制就像一个哨兵一样,时刻监视着主从节点的运行状态,当主节点出现故障导致不可用时,自动从从节点中选举一个数据完整,状态良好的节点作为新的主节点提供服务,实现主节点的高可用。
  • 在实现层面,sentinel也是以Redis服务器的方式运行,可以发送和接收命令,只是不支持数据操作相关的命令,如可以发生INFO,PUBLISH,SUBSCRIBE命令,但是不支持SET,GET之类的命令。

Sentinel哨兵机制的配置与启动

配置文件

  • 在redis的根目录下面,即与redis.conf同级,存在一个sentinel.conf,这个配置文件就是哨兵机制的配置文件。主要内容如下:

    # port <sentinel-port>
    # The port that this sentinel instance will run on
    # 运行端口号
    port 26379
    
    # sentinel monitor <master-name> <ip> <redis-port> <quorum>
    #
    # Tells Sentinel to monitor this master, and to consider it in O_DOWN
    # (Objectively Down) state only if at least <quorum> sentinels agree.
    #
    # Note that whatever is the ODOWN quorum, a Sentinel will require to
    # be elected by the majority of the known Sentinels in order to
    # start a failover, so no failover can be performed in minority.
    #
    # Slaves are auto-discovered, so you don't need to specify slaves in
    # any way. Sentinel itself will rewrite this configuration file adding
    # the slaves using additional configuration options.
    # Also note that the configuration file is rewritten when a
    # slave is promoted to master.
    #
    # Note: master name should not include special characters or spaces.
    # The valid charset is A-z 0-9 and the three characters ".-_".
    
    # 该哨兵监视的主服务器ip和端口号,2表示包括自身在内,
    # 如果存在两个监视该主服务器的哨兵认为该主服务器主观下线,则升级为客观下线。
    sentinel monitor mymaster 127.0.0.1 6379 2
    
    # sentinel down-after-milliseconds <master-name> <milliseconds>
    #
    # Number of milliseconds the master (or any attached slave or sentinel) should
    # be unreachable (as in, not acceptable reply to PING, continuously, for the
    # specified period) in order to consider it in S_DOWN state (Subjectively
    # Down).
    #
    # Default is 30 seconds.
    
    # 判断主观下线的时间,即哨兵以每秒1次的频率发送PING给主服务器,
    # 如果连续超过30秒,主服务器都返回无效响应,
    # 则该哨兵认为主服务器主观下线。
    sentinel down-after-milliseconds mymaster 30000
    

启动方式

  • 在配置文件sentinel.conf配置好需要监视的主服务器之后,则通过以下命令来启动该哨兵:

    redis-sentinel sentinel.conf
    或者
    redis-server sentinel.conf --sentinel
    

Sentinel哨兵机制的实现

1. 配置文件解析与建立连接

  • 哨兵启动时,会解析sentinel.conf配置文件,获取被监控的主服务器信息,在内部创建该主服务器的实例信息。

  • 然后哨兵作为客户端,与Redis主服务器建立命令连接和订阅连接这两条连接,其中命令连接用于发送命令给主服务器,如INFO命令获取主服务器的运行状态信息;订阅连接用于往主服务器的 __ sentinel:hello __ 主题发布PUBLISH该哨兵的信息,从该主题订阅SUBSCRIBE获取监视该主服务器的其他哨兵的信息。

  • 每隔10秒:通过命令连接发送INFO命令给被监视的主服务器或从服务器,获取其状态信息;刚开始时,哨兵通过配置获取其监视的主服务器,然后通过主服务器的INFO信息获取该主服务器的从服务器信息,从而间接获取该从服务器的信息,然后与从服务器也建立命令和订阅两条连接,即实现自动发现该主服务器的从服务器列表;

  • 每隔2秒:通过命令连接向 __ sentinel:hello __ 主题PUBLISH该哨兵自身和所监视的主服务器的信息,通过订阅连接订阅SUBSCRIBE该 __ sentinel:hello __ 主题的消息,从而间接获取与该哨兵监视同一个主服务器的其他哨兵的信息,并在该哨兵内部的主服务器实例维护这些其他的哨兵信息。所以订阅连接的主要作用是哨兵自动发现其他监视了这个主服务器或者从服务器的哨兵的存在。

2. 与其他哨兵建立连接

  • 在每个哨兵内部针对每个被监视的主服务器都维护了一个sentinels字典,保存了与该哨兵监视同一个主服务器的其他哨兵的字典,在订阅 __ sentinel:hello __ 获取到其他哨兵的信息时,更新该字典中对应的哨兵实例,从而自动发现其他哨兵的存在。

  • 在哨兵通过发布订阅发现监视同一个服务器的其他哨兵后,会建立与其他哨兵的命令连接,从而实现监视同一个服务器的多个哨兵建立互相连接的网络,即哨兵A有连向哨兵B的命令连接,哨兵B也有连向哨兵A的命令连接。这样只会哨兵之间可以通过该命令连接来相互交换信息。

3. 监视与主观下线

  • 每隔1秒:哨兵会每秒一次向其所监视的主服务器,从服务器,关联的其他哨兵发送一个PING,如果对方返回+PONG,-LOADING(主服务器和从服务器的返回),-MASTERDOWN(其他哨兵的返回)三种回复的其中一种,则认为是有效回复,除此之外的或者指定时间内没有回复,则认为是无效回复。如果在down-after-millisenconds时间内连续返回无效回复,则哨兵会将该主服务器,从服务器或者哨兵置为主观下线。接着进入判断是否客观下线的流程。

4. 客观下线

  • 由于监视同一个主服务器的多个哨兵之间建立了相互连接的网络,故当某个哨兵将主服务器置为主观下线之后,该哨兵会通过与其他哨兵的命令连接发送is-master-down-by-addr <current_epoch> 命令来询问其他哨兵是否也将该主服务器置为主观下线了。如果其他哨兵有回复主观下线的且当回复是主观下线的达到一定比例,具体个数由配置文件配置,如下为2个:sentinel master port 127.0.0.1 6379 2,即包括自身在内,如果有两个哨兵认为主服务器主观下线了,则该哨兵将该主服务器置为客观下线。
  • 不同哨兵的判断客观下线可能配置不一样,但是只要有一个哨兵做出了客观下线的决定,则就开始哨兵的leader选举和产生新的主服务器。

5. 哨兵leader选举

  • 当一个哨兵认为主服务器客观下线了,则会开始哨兵leader选举,由该leader负责该下线的主服务器的故障处理和产生新的主服务器。
  • leader选举基本过程为:检测到客观下线的每个哨兵都向全体哨兵发送is-master-down-by-addr命令,在命令中带上自己的runid,要求接受到这个命令的哨兵设置该发送命令的哨兵为局部leader,并回复该发送命令的哨兵,如果该发送命令的哨兵发现自己收到了超过半数的哨兵将自己设置为了局部leader,则选举结束,该哨兵成为leader哨兵。

6. 主服务器切换

  • 哨兵leader负责故障处理,主要为从从服务器列表选举一个从服务器作为新的主服务器。具体为:
    1. 从下线的主服务器的从服务器列表中(排除已经断线、5秒内没有回复过sentinel的INFO命令、与原主服务器断开超过10 * down-after-milliseconds毫秒的从服务器,排除完之后根据优先级选举优先级最高的从服务器,如果优先级相同,则选举复制偏移量最大的,如果复制偏移量相同,则选择运行id最小的)选举一个状态良好、数据完整的从服务器作为新的主服务器:发送SLAVE no one;每秒一次发送INFO命令检查该从服务器是否已经升级为了主服务器;
    2. 将原主服务器下面的所有从服务器对应的主服务器更新为这个新的主服务器:通过命令连接发送SLAVEOF <新的主服务器ip> …给从服务器 ;
    3. 将原主服务器更新为新的主服务器的一个从服务器,等原主服务器重启后时,同步该新的主服务器的数据,成为该新的主服务器的一个从服务器:修改哨兵内部维护的该主服务器的信息,等该故障服务器重新上线后,发送SLAVEOF命令。

猜你喜欢

转载自blog.csdn.net/u010013573/article/details/88243663