欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

谈谈Redis的哨兵机制

程序员文章站 2022-07-13 11:12:39
...

1. 背景

       一般来说,在工作上用到redis集群,基本上都是主从模式,说的更细致一点,是主从复制模式。在Redis 2.8版本之前,主从复制的模式下,一旦主节点发生故障不能提供服务,一般都是手动的将主节点下掉,把从节点提升为主节点,然后再通知客户端更新主节点的地址,这种方式在很大程度上是难以让人接受的。

       为什么这么说呢,这里就是一个Redis高可用的问题。通常的web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务,这里肯定是有一个指标的。在redis层面,高可用的含义要宽泛一些,不仅仅是保证提供正常服务,如主从分离,快速容灾等等,也需要考虑数据容量扩容,数据安全等等。在实现redis高可用的技术主要包括:持久化,复制,哨兵,集群。下面就简单的说说它们的作用,以及解决什么样的问题。

  • 持久化:持久化是最简单的高可用方法。它的主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
  • 复制:复制是高可用Redis的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制。
  • 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷是写操作无法负载均衡,存储能力受到单机的限制。
  • 集群:通过集群,Redis解决了写操作无法负载均衡以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

本篇着重分析下redis的哨兵机制

 

2. Redis的哨兵机制

       Redis的哨兵(Sentinel)是Redis高可用的实现方案之一,Sentinel是一个管理多个Redis实例的工具,它可以实现对Redis的监控、通知、自动故障转移。通过下面一张图说明下Redis Sentinel的基本概念。

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

哨兵的基本概念介绍完了,下面来看下Redis的主从复制模式及哨兵的高可用架构。

 

3. Redis主从复制模式

 

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

3.1 优点

        Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:

  • 主节点宕机,从节点作为主节点的备份可以随时顶上来。
  • 扩展主节点的读能力,分担主节点读压力。

3.2 缺点

  • 如果主节点宕机,那么从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
  • 主节点的写能力受到单机的限制。
  • 主节点的存储能力受到单机的限制。
  • 原生复制的弊端在早期的版本中也会比较突出,比如:Redis复制中断后,从节点会发起psync。此时如果同步不成功,则会进行全量同步,主库执行全量备份的同时,可能会造成毫秒或秒级的卡顿。

4. Redis Sentinel架构

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

4.1 Redis Sentinel的主要功能      

       Redis Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移(failover)、主从切换。Redis的Sentinel最小配置是一主一从。

        Redis的Sentinel系统可以用来管理多个Redis服务器,该系统可以执行以下四个任务:

  • 监控:Sentinel会不断的检查主服务器和从服务器是否正常运行。
  • 通知:当被监控的某个Redis服务器出现问题,Sentinel通过API脚本向管理员或者其他的应用程序发送通知。
  • 自动故障转移:当主节点不能正常工作时,Sentinel会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点,并且将其他的从节点指向新的主节点。
  • 配置提供者:在Redis Sentinel模式下,客户端应用在初始化时连接的是Sentinel节点集合,从中获取主节点的信息。

4.2 主管下线和客观下线

       默认情况下,每个Sentinel节点会以每秒一次的频率对Redis节点和其它的Sentinel节点发送PING命令,并通过节点的回复来判断节点是否在线。

       主观下线:适用于所有主节点和从节点。如果在down-after-milliseconds毫秒内,Sentinel没有收到目标节点的有效回复,则会判定该节点为主观下线。

       客观下线:只适用于主节点。如果主节点出现故障,Sentinel节点会通过sentinel is-master-down-by-addr命令,向其它Sentinel节点询问对该节点的状态判断。如果超过 <quorum> 个数的节点判定主节点不可达,则该Sentinel节点会判断主节点为客观下线。

 

4.3 哨兵(Sentinel)的通信命令

       Sentinel节点连接一个Redis实例的时候,会创建cmd和pub/sub两个连接。Sentinel通过cmd连接给Redis发送命令,通过pub/sub连接到Redis实例上的其他Sentinel实例。如下表所示:

场景 命令 作用
Sentinel与Redis主节点和从节点交互的命令 PING Sentinel向Redis节点发送PING命令,检查节点的状态。
  INFO Sentinel向Redis节点发送INFO命令,获取它的从节点信息。
  PUBLISH Sentinel向其监控的Redis节点 __sentinel__:hello这个channel发布自己的信息及主节点相关的配置。
  SUBSCRIBE Sentinel通过订阅Redis主节点和从节点的__sentinel__:hello这个channnel,获取正在监控相同服务的其他Sentinel节点。
Sentinel与Sentinel交互的命令 PING Sentinel向其他Sentinel节点发送PING命令,检查节点的状态。
  SENTINEL:is-master-down-by-addr 和其他Sentinel协商主节点的状态,如果主节点处于SDOWN状态,则投票自动选出新的主节点。

 

5. Redis Sentinel的工作原理

       每个Sentinel节点都需要定期执行以下任务:

       a. 每个Sentinel以每秒钟一次的频率,向它所知的主服务器、从服务器以及其他Sentinel实例发送一个PING命令。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       b. 如果一个实例(instance)距离最后一次有效回复PING命令的时间超过down-after-milliseconds所指定的值,那么这个实例会被Sentinel标记为主观下线。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       c. 如果一个主服务器被标记为主观下线,那么正在监视这个主服务器的所有Sentinel节点,要以每秒一次的频率确认主服务器的确进入了主观下线状态。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       d. 如果一个主服务器被标记为主观下线,并且有足够数量的Sentinel(至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断,那么这个主服务器被标记为客观下线。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       e. 在一般情况下,每个Sentinel会以每10秒一次的频率,向它已知的所有主服务器和从服务器发送INFO命令。当一个主服务器被Sentinel标记为客观下线时,Sentinel向下线主服务器的所有从服务器发送INFO命令的频率,会从10秒一次改为每秒一次。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       f. Sentinel和其他Sentinel协商主节点的状态,如果主节点处于SDOWN状态,则投票自动选出新的主节点。将剩余的从节点指向新的主节点进行数据复制。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       g. 当没有足够数量的Sentinel同意主服务器下线时, 主服务器的客观下线状态就会被移除。当主服务器重新向Sentinel的PING命令返回有效回复时,主服务器的主观下线状态就会被移除。如下图所示:

谈谈Redis的哨兵机制
            
    
    博客分类: Redis架构  

 

       注意:一个有效的PING回复可以是:+PONG、-LOADING或者-MASTERDOWN。如果服务器返回除以上三种回复之外的其他回复,又或者在指定时间内没有回复PING命令, 那么Sentinel认为服务器返回的回复无效(non-valid)。

 

6. 总结

       关于redis的哨兵机制,一部分出了自己在工作中累积而来,还有一部分是阅读了《Redis开发与运维》。如有其他见解的小伙伴,可以在下面留言,我们一起探讨。