一、引言

上一篇文章我们详细的讲解了Redis的主从集群模式,其实这个集群模式配置很简单,只需要在Slave的节点上进行配置,Master主节点的配置不需要做任何更改,但是有一点,Master和Slave两个节点的持久化配置 尽量保持一致,否则会有奇怪的问题出现。从今天开始我们开始讲Redis集群模式的第二模式,也就是**“哨兵”模式**,该模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来,在生产环境中,如果想要使用Redis的哨兵模式,也会尽量使用Redis的2.8版本之后的版本。无论是主从模式,还是哨兵模式,这两个模式都有一个问题,不能水平扩容,并且这两个模式的高可用特性都会受到Master主节点内存的限制。还有一点,实现哨兵模式的配置也不简单,甚至可以说有些繁琐,所以在工业场景里这两个模式都不建议使用,如果要使用,必须有相关的问题的解决方案,以免后续带来的问题。

二、Redis Sentinel简介

Sentinel(哨兵)进程 是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。

哨兵(Sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定 是否执行 自动故障迁移,以及选择哪个Slave作为新的Master

主观宕机、客观宕机:

  • 每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、MasterSlave 定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,英文名称:Subjective Down,简称SDOWN。
  • 当“哨兵群”中的多数Sentinel进程对Master主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是 “客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。

哨兵(sentinel) 虽然有一个单独的可执行文件 redis-sentinel,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel),哨兵(sentinel) 的一些设计思路和zookeeper非常类似。

Sentinel集群之间会互相通信,沟通交流redis节点的状态,做出相应的判断并进行处理,这里的主观下线状态和客观下线状态是比较重要的状态,它们决定了是否进行故障转移,可以通过订阅指定的频道信息,当服务器出现故障的时候,通知管理员。客户端可以将 Sentinel 看作是一个只提供了订阅功能的 Redis 服务器,你不可以使用 PUBLISH 命令向这个服务器发送信息,但你可以用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令, 通过订阅给定的频道来获取相应的事件提醒。一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。

2.1 Sentinel(哨兵)进程的作用:

1】、监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常

2】、提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序 发送通知

3】、自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,新的Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

2.2 Sentinel(哨兵)进程的工作方式:

1】、每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器、Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令

2】、如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程 标记为 主观下线(SDOWN)

3】、如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。

4】、当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内 确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)。

5】、在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令

6】、当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次

7】、若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令 返回有效回复,Master主服务器的 主观下线状态 就会被移除

2.3 哨兵模式的环境:

1】、Master主服务器配置信息:IP:192.168.127.128, Port:6379,OS:Linux

2】、Slave从服务器的配置信息:IP:192.168.127.129 Port:6379,OS:Linux

3】、在Slave从服务器上安装了一个哨兵进程(Sentinel),在Master服务器也安装了一个哨兵进程(Sentinel)。

由于两个Redis服务器都是安装在Linux操作系统上,而且这两个Redis服务器会在Master主服务器发生故障的时候会进行切换,必须保证两个Redis服务器的端口号已经增加进了防火墙或者把两个Linux操作系统的防火墙关闭,否则会提示Master-link-Status:down,没有连接上Master主服务器

解决办法有两个:

第一个办法是关闭两个Linux操作系统的防火墙

第二个办法是把各个Redis服务的端口号增加到防火墙里面,允许通过该端口号进行通信。可以先使用命令 【firewall-cmd --query-port=6379/tcp】,如果结果是 No,那就继续执行以下命令【firewall-cmd --add-port=6379/tcp】,命令执行后,返回Success,表示增加成功。这样两个Linux系统上的Redis服务器就可以顺利切换执行哨兵模式的操作

三、主观下线和客观下线

下面我们来解释一下两个“下线”的概念,一个是“主观下线”,另一个就是“客观下线”。

主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。

客观下线(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(哨兵)进程就会将这个服务器标记为主观下线

服务器对 PING 命令的有效回复可以是以下三种回复的其中一种:

  • 1、返回 +PONG 。
  • 2、返回 -LOADING 错误。
  • 3、返回 -MASTERDOWN 错误。

如果服务器返回除以上三种回复之外的其他回复,又或者在指定时间内没有回复 PING 命令,那么 Sentinel(哨兵)进程认为服务器返回的回复无效(non-valid)。

如果一个服务器在 master-down-after-milliseconds 毫秒内,一直返回无效回复才会被 Sentinel 标记为主观下线。

举个例子,如果 master-down-after-milliseconds 选项的值为 30000 毫秒(30 秒),那么只要服务器能在每 29 秒之内返回至少一次有效回复, 这个服务器就仍然会被认为是处于正常状态的。

从“主观下线”状态切换到“客观下线”状态并没有使用严格的法定人数算法(strong quorum algorithm),而是使用了流言协议,该协议解释为:如果 Sentinel(哨兵)进程在给定的时间范围内从其他 Sentinel(哨兵)进程那里接收到了足够数量主服务器下线报告, 那么 Sentinel(哨兵)进程就会将主服务器的状态从 “主观下线” 改变为 “客观下线”。如果之后其他 Sentinel(哨兵)进程不再报告主服务器已下线,那么“客观下线”状态就会被移除。

客观下线”条件只适用于主服务器:对于任何其他类型的 Redis 实例, Sentinel(哨兵)进程在将它们判断为下线前不需要进行协商,所以Slave从服务器或者其他 Sentinel(哨兵)进程永远不会达到“客观下线”条件。

只要有一个 Sentinel(哨兵)进程发现某个主服务器进入了“客观下线”状态,这个 Sentinel(哨兵)进程就可能会被其他 Sentinel(哨兵)进程推选出,并对失效的主服务器执行自动故障迁移操作

四、哨兵模式的优缺点

优点:

1、哨兵集群模式是基于主从模式的,所有主从的优点哨兵模式同样具有

2、主从可以切换故障可以转移系统可用性更好

3、哨兵模式是主从模式的升级,系统更健壮,可用性更高。

缺点:

1、Redis较难支持在线扩容,在集群容量达到上限时,在线扩容 会变得 很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

五、结束

今天就写到这里了,Redis的哨兵模式是以主从模式为基础的,所以说,主从模式拥有的一些缺点,在哨兵模式下也具有。哨兵模式主要是监控Master主服务器的运行情况,当然也会监控Slave从服务器的运行情况,如果Master主服务器发生了故障,该模式可以保证Slave从服务器顺利升级为Master主服务器继续提供服务,以此提高系统的高可用性。虽然哨兵模式比主从模式提高了不少系统的高可用性,但是该模式不能水平扩容不能动态的增、删节点,这也是限制哨兵模式广泛应用的主要原因。Redis也看到了这个情况,所在在Redis的3.x以后的版本提供了一个更加强大集群模式,那就是Cluster集群模式,这个模式也是我们下一篇文章的主题。