• redis高可用结构sentinel工作机制


    Redis-Sentinel(哨兵)是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

    Sentinel 的构造

    Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。
     

    sentinel功能

     
    监控(Monitoring):
      Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
     
    提醒(Notification):
      当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
     
    自动故障迁移(Automatic failover):
      当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
     
     

    发现并连接主服务器

    Sentinel 通过用户给定的配置文件来发现主服务器。
    Sentinel 会与被监视的主服务器创建两个网络连接:
    • 命令连接用于向主服务器发送命令。
    • 订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel (细节马上会介绍)。
     
     

    发现并连接从服务器

    Sentinel 通过向主服务器发送 INFO 命令来自动获得所有从服务器的地址。

    跟主服务器一样,Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接。

    发现其他 Sentinel

    Sentinel 会通过命令连接向被监视的主从服务器发送 “HELLO” 信息,该消息包含 Sentinel 的 IP、端口号、ID 等内容,以此来向其他 Sentinel 宣告自己的存在。与此同时Sentinel 会通过订阅连接接收其他 Sentinel 的“HELLO” 信息,以此来发现监视同一个主服务器的其他 Sentinel 。

     
    sentinel1 通过发送HELLO 信息来让sentinel2 和 sentinel3发现自己,其他两个sentinel 也会进行类似的操作。
     

    多个Sentienl之间的链接

    Sentinel 之间只会互相创建命令连接,用于进行通信。因为已经有主从服务器作为发送和接收 HELLO 信息的中介,所以 Sentinel之间不会创建订阅连接。

    检测实例的状态

     
    Sentinel 使用 PING 命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被 Sentinel 判断为下线。
    Redis 的 Sentinel 中关于下线(down)有两个不同的概念:
    1. 主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
    2. 客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线。)
    如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线。

    故障转移FAILOVER

    一次故障转移操作由以下步骤组成:
    1. 发现主服务器已经进入客观下线状态。
    2. 基于Raft leader election  协议 , 进行投票选举(半数以上)
    3. 如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。 如果当选成功, 那么执行以下步骤。
    4. 选出一个从服务器,并将它升级为主服务器。
    5. 向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
    6. 通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel ,其他 Sentinel 对它们自己的配置进行更新。
    7. 向已下线主服务器的从服务器发送 SLAVEOF 命令,让它们去复制新的主服务器。
    8. 当所有从服务器都已经开始复制新的主服务器时, leader Sentinel 终止这次故障迁移操作。

    搭建sentinel环境并且测试主从切换

    1. 前提:在搭建之前一定要确认redis主从复制是正常的,这里我们有三个节点6381(主节点)、6380和6382(从节点)

    [root@master_1 ~]# redis-cli -a 123 -p 6381 info replication
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=127.0.0.1,port=6382,state=online,offset=19846,lag=1
    slave1:ip=127.0.0.1,port=6380,state=online,offset=19846,lag=1
    ...
    

    主从是ok的

    2. sentinel搭建过程
     
    mkdir /data/26380
    cp /server/tools/redis/src/redis-sentinel /data/26380
    cd /data/26380
    

       

    vim sentinel.conf # 官方提供的示例配置文件在redis的安装目录下/server/tools/redis/sentinel.conf
    daemonize yes
    port 26380
    dir "/data/26380"
    logfile "/data/26380/sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6381 1
    sentinel down-after-milliseconds mymaster 3000
    sentinel auth-pass mymaster 123
    

      

    注意:如果redis中都设置了密码这里需要加上密码
     
    3. 启动
     /data/26380/redis-sentinel /data/26380/sentinel.conf
    [21502:X 25 Sep 2019 16:35:52.068 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    21502:X 25 Sep 2019 16:35:52.068 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=21502, just started
    21502:X 25 Sep 2019 16:35:52.068 # Configuration loaded
    21503:X 25 Sep 2019 16:35:52.073 * Running mode=sentinel, port=26380.
    21503:X 25 Sep 2019 16:35:52.082 # Sentinel ID is ff2fe375b2c6dc7e0da91f5bd72743504057c738
    21503:X 25 Sep 2019 16:35:52.086 # +monitor master mymaster 127.0.0.1 6381 quorum 1
    21503:X 25 Sep 2019 16:35:52.088 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:35:52.090 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
    
    已经正常启动sentinel了,并且正常监控到了6381端口,并且获取到了两个slave的状态

     
    配置文件详解

    指定监控master(名字自己定义)
    sentinel monitor mymaster 127.0.0.1 6381 2
    {2表示多少个sentinel同意,才确认redis主节点已经下线了。}
    
    安全信息
    sentinel auth-pass mymaster 123
    
    超过15000毫秒后认为主机宕机
    sentinel down-after-milliseconds mymaster 15000  
    
    当主从切换多久后认为主从切换失败
    sentinel failover-timeout mymaster 900000
    
    这两个配置后面的数量主从机需要一样,epoch为master的版本
    sentinel leader-epoch mymaster 1
    sentinel config-epoch mymaster 1
    

      

    4. 停主库测试测试故障切换是否正常:
    [root@master_1 26380]# redis-cli -a 123 -p 6381 shutdown
    

     

    查看sentinel的日志信息

    21503:X 25 Sep 2019 16:39:26.489 # +sdown master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.489 # +odown master mymaster 127.0.0.1 6381 #quorum 1/1
    21503:X 25 Sep 2019 16:39:26.489 # +new-epoch 1
    21503:X 25 Sep 2019 16:39:26.489 # +try-failover master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.492 # +vote-for-leader ff2fe375b2c6dc7e0da91f5bd72743504057c738 1
    21503:X 25 Sep 2019 16:39:26.492 # +elected-leader master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.492 # +failover-state-select-slave master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.545 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.545 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:26.608 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:27.561 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:27.561 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:27.625 * +slave-reconf-sent slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:28.589 * +slave-reconf-inprog slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:28.589 * +slave-reconf-done slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:28.689 # +failover-end master mymaster 127.0.0.1 6381
    21503:X 25 Sep 2019 16:39:28.689 # +switch-master mymaster 127.0.0.1 6381 127.0.0.1 6380
    21503:X 25 Sep 2019 16:39:28.689 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
    21503:X 25 Sep 2019 16:39:28.689 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
    21503:X 25 Sep 2019 16:39:31.700 # +sdown slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
    
    可以看出过了3秒后,通过投票选出了新主 6380,然后把6381和6382都指向了6380,指出6381已经挂掉了。

    5. 启动源主库(6381)并检查状态。

    redis-server /data/6381/redis.conf
    

      

    [root@master_1 26380]# redis-cli -a 123 -p 6381 info replication
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    # Replication
    role:slave
    master_host:127.0.0.1
    master_port:6380
    master_link_status:up
    ...
    

    可以看出sentinel已经把它指定新的redis主

    6. 这里有一个需要注意的点就是sentinel会自动修改配置文件

    这里我们查一下配置文件
    [root@master_1 26380]# cat /data/26380/sentinel.conf

    daemonize yes
    port 26380
    dir "/data/26380"
    logfile "/data/26380/sentinel.log"
    sentinel myid ff2fe375b2c6dc7e0da91f5bd72743504057c738
    sentinel deny-scripts-reconfig yes
    sentinel monitor mymaster 127.0.0.1 6380 1
    # Generated by CONFIG REWRITE
    protected-mode no
    sentinel down-after-milliseconds mymaster 3000
    sentinel auth-pass mymaster 123
    sentinel config-epoch mymaster 1
    sentinel leader-epoch mymaster 1
    sentinel known-replica mymaster 127.0.0.1 6381
    sentinel known-replica mymaster 127.0.0.1 6382
    

      

    Sentinel命令

    redis-cli -p 26380 登录执行命令
     
     
    PING :返回 PONG 。
    SENTINEL masters :列出所有被监视的主服务器
    SENTINEL slaves <master name>
    SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。
    SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。
    SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。

      

     

     

  • 相关阅读:
    java 九个预定义Class对象
    Android github上开源项目、酷炫的交互动画和视觉效果地址集合
    Axure多人协作
    尺取法
    android binder 机制二(client和普通server)
    11-11前的电商
    用minGW编译ffmpeg(供替换opencv中引用的ffmpeg库)
    设计模式_状态模式
    六句代码实现对文件按时间的重命名,
    在QML应用中实现threading多任务
  • 原文地址:https://www.cnblogs.com/yang-ning/p/11642614.html
Copyright © 2020-2023  润新知