前言

  当按照上一篇《redis主从复制》部署好之后,我们会想,一旦redis的master出现了宕机,并且我们并没有及时发现,这时候就可能会出现数据丢失或程序无法运行。此时,redis的哨兵模式就派上用场了,可以用它来做redis的高可用。

 

功能作用

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

 

部署

  同样,我们还是将每个哨兵部署在一个单独的容器中。

  sentinel配置文件

  redis-sentinel1:https://github.com/Johnson19900110/johnsondock/blob/master/redis-sentinel/config/sentinel.conf

  redis-sentinel2:https://github.com/Johnson19900110/johnsondock/blob/master/redis-sentinel/config/sentinel-slave1.conf

  redis-sentinel3:https://github.com/Johnson19900110/johnsondock/blob/master/redis-sentinel/config/sentinel-slave2.conf

  这三个配置文件一模一样,都是监听master的。要不你把这个配置文件copy到容器中,要不你就创建三份,分别挂载到容器中,这里选择了后面一种方法。

  这里介绍几个基本的配置

    sentinel monitor mymaster redis 6379 2 监听的master的容器别名为redis,端口是6379,最后面的2是当大于等于2个哨兵认为master主观下线后(无论这个值为多少,至少得有一半以上的哨兵判定master主观下线后,master才会被客观下线),master才会被客观下线,这是sentinel重新从slave中选举一个来当master。

    sentinel auth-pass mymaster 123456 如果master配置了密码,则此项必须配置,否则sentinel会将master标记问主观下线(sdown)。

 

  docker-composer配置文件


### REDIS-SENTINEL ################################################
  # master
  redis-sentinel:
    image: johnson19900110/redis-sentinel:latest
    restart: always  #如果master未开启数据持久化,此项应该删除
    volumes:
      - ./redis-sentinel/config/sentinel.conf:/usr/local/etc/redis/redis-sentinel.conf
    networks:
      - backend
    depends_on:
      - redis

  # redis sentinel slave 1
  redis-sentinel-slave1:
    image: johnson19900110/redis-sentinel:latest
    restart: always
    volumes:
      - ./redis-sentinel/config/sentinel-slave1.conf:/usr/local/etc/redis/redis-sentinel.conf
    networks:
      - backend
    depends_on:
      - redis-slave1
      - redis-sentinel

  # redis sentinel slave 2
  redis-sentinel-slave2:
    image: johnson19900110/redis-sentinel:latest
    restart: always
    volumes:
      - ./redis-sentinel/config/sentinel-slave2.conf:/usr/local/etc/redis/redis-sentinel.conf
    networks:
      - backend
    depends_on:
      - redis-slave2
      - redis-sentinel-slave1



  

启动容器



docker-compose up -d redis-sentinel-slave2



执行以上命令后,就启动了三个哨兵模式的容器

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_后端

这是我们进入容器,查看是否redis-sentinel是否在工作。 

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_redis哨兵为什么至少三台_02

我们可看到,已经与master建立连接,通过status=ok可以知道,master正在正常工作,并且有2个从节点和3个哨兵节点。现在你再打开sentinel的配置文件,会发现发生了改变。

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_运维_03

conf文件被重写了,并且哨兵模式会自动检测到master的两个slave和另外两个sentinel。

 

故障演示

  1、使master宕机,只需要关闭master的容器即可。 

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_数据库_04

如果此时再去三个哨兵节点里用info sentinel查看信息。

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_运维_05

会发现这时候master节点的address信息变了,这就说明哨兵模式起作用了。但他这里还是显示新的master有两个slave。是因为原master节点宕机了,一旦它重启,sentinel就会把它变成新的master节点的slave节点。我们可以去172.18.0.6这个容器中看下。

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_运维_06

可以用以上docker命令查看容器的IP地址。进入容器后,还是在redis-cli下用info replication查看信息。 

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_redis_07

我们可以看到这个slave变成了新的master,另外一个slave也变成了新master节点的slave。如果你查看redis节点的配置文件,会发现也被重写了。 这是我们再重启原master节点试试(注意:当他重启成功后,就变成了slave节点,所以要打开持久化配置)。

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_运维_08

当容器重启成功后,我们再去新的master节点中使用info replication查看下。

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_redis哨兵为什么至少三台_09

正如我们所料,它成为了新的master的slave节点。如果你查看原master的配置文件,会发现多了 

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_redis哨兵为什么至少三台_10

最后,因为新的master节点是slave节点升级的,所以他的持久化配置还是存在的,如果你想要关掉它,只需要进入redis-cli,然后执行

redis哨兵为什么至少三台 redis哨兵模式哨兵挂了_redis哨兵为什么至少三台_11

至此,一次redis的master节点故障转移就演示完成了。这次演示实现了redis的监控自动故障转移特性。

提醒特性是使用的订阅功能,需要后端代码开发配合的。

 

发布与订阅信息

客户端可以将 Sentinel 看作是一个只提供了订阅功能的 Redis 服务器: 你不可以使用 PUBLISH 命令向这个服务器发送信息, 但你可以用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令, 通过订阅给定的频道来获取相应的事件提醒。

一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。

通过执行 PSUBSCRIBE * 命令可以接收所有事件信息。

以下列出的是客户端可以通过订阅来获得的频道和信息的格式: 第一个英文单词是频道/事件的名字, 其余的是数据的格式。

注意, 当格式中包含 instance details 字样时, 表示频道所返回的信息中包含了以下用于识别目标实例的内容:


@ 字符之后的内容用于指定主服务器, 这些内容是可选的, 它们仅在 @ 字符之前的内容指定的实例不是主服务器时使用。

  • +reset-master :主服务器已被重置。
  • +slave :一个新的从服务器已经被 Sentinel 识别并关联。
  • +failover-state-reconf-slaves :故障转移状态切换到了 reconf-slaves 状态。
  • +failover-detected :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。
  • +slave-reconf-sent :领头(leader)的 Sentinel 向实例发送了 [SLAVEOF](/commands/slaveof.html) 命令,为实例设置新的主服务器。
  • +slave-reconf-inprog :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。
  • +slave-reconf-done :从服务器已经成功完成对新主服务器的同步。
  • -dup-sentinel :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。
  • +sentinel :一个监视给定主服务器的新 Sentinel 已经被识别并添加。
  • +sdown :给定的实例现在处于主观下线状态。
  • -sdown :给定的实例已经不再处于主观下线状态。
  • +odown :给定的实例现在处于客观下线状态。
  • -odown :给定的实例已经不再处于客观下线状态。
  • +new-epoch :当前的纪元(epoch)已经被更新。
  • +try-failover :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by the majority)。
  • +elected-leader :赢得指定纪元的选举,可以进行故障迁移操作了。
  • +failover-state-select-slave :故障转移操作现在处于 select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。
  • no-good-slave :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。
  • selected-slave :Sentinel 顺利找到适合进行升级的从服务器。
  • failover-state-send-slaveof-noone :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。
  • failover-end-for-timeout :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。
  • failover-end :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
  • +switch-master :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。
  • +tilt :进入 tilt 模式。
  • -tilt :退出 tilt 模式。