• Redis_09_Redis集群实现Sentinel哨兵应对高可用


    一、前言

    二、Sentinel原理

    2.1 Sentinel原理

    在这里插入图片描述
    Redis的高可用是通过哨兵Sentinel来保证的,如下:
    在这里插入图片描述

    思路是:通过运行监控服务器来保证服务的高可用。从Redis 2.8 版本开始,提供了一个稳定版本的Sentinel,用来解决高可用的问题。我们会启动奇数个Sentinel服务。Sentinel 本质只是一个运行在特殊模式下的Redis。Sentinel通过 info 命令得到被监听的 Redis 机器的 master slave 等信息。

    为了保证监控服务器的可用性,我们会对Sentinel做集群的部署。Sentinel既监控所有的Redis服务,Sentinel之间也相互监控。另外,Sentinel本身没有主从之分,地位是平等的,只有Redis服务节点有主从之分。

    各个 Sentinel 之间唯一的联系,就是他们监控相同的 master,那一个Sentinel节点怎么知道其他Sentinel节点的存在?答案是发布订阅(Pub/Sub)的功能。

    Sentinel 是一个特殊状态的Redis节点,所有它也有发布订阅的功能。

    哨兵上线时,给所有的Redis节点(包括master和node)的名字为 sentinel:hello 的 channel 发送消息。
    每个哨兵都订阅了所有Redis节点名为 sentinel:hello 的channel,所有互相都能感知到对方的存在,而从进行监控。

    2.2 Sentinel选主

    Redis 主从结构,主节点宕机之后,对于所有的从节点,一共有四个因素影响选举结果,分别是断开连接时长、优先级排序、复制数量、进程Id。

    1、如果与哨兵连接断开的比较久,超过某个阈值,就直接失去了选举权。
    2、对于所有拥有选举权的从节点,看谁的优先级高,这个在配置文件中可以设置,默认优先级为100,数值越小优先级越高。
    3、对于所有拥有选举权的从节点,如果有优先级相同,看哪个从节点从master中复制的数据最多(就是offset),选offset最大的那个。
    4、对于所有拥有选举权的从节点,如果优先级和offset相同,选进程id最小的那个。

    关于redis.conf中的 优先级,默认是 100
    在这里插入图片描述

    在这里插入图片描述

    基本上redis.conf里面的属性,都可以在 redis-cli 可以查看,命令为 config get 属性名

    2.3 Sentinel哨兵的四个功能

    “哨兵集群Sentinel”:哨兵是一个一个的,通过哨兵来完成四个功能:集群监控(master宕机了就要选主)、消息通知、故障转移、配置中心,囊括所有哨兵的集群就是Sentinel。

    哨兵组件的四个功能:

    1、集群监控:Snetinel 会不断检查主服务器和从服务器是否正常运行。
    2、消息通知:如果某个被监控的实例出现了问题,Sentinel 可以通过 api 发出通知。
    3、故障转移:如果主服务器发生故障,比如执行shutdown模拟宕机,Sentinel 可以启动故障转移功能,将某台从服务器升级为主服务器,自动选主,保证高可用。
    4、配置中心:客户端redis-cli 连接到Sentinel,获取当前的Redis主服务器的地址。

    2.4 最简单是Redis哨兵主从结构至少需要三个机器

    最简单是Redis哨兵主从结构至少需要三个机器(通常哨兵/Redis节点都是奇数个)

    为什么至少需要三个实例呢?我们先看看两个哨兵会咋样,如下图:

    两个机器,每个机器上都是一个 redis节点6379端口 + 一个哨兵Sentinel 26379 端口,如下图:M1 表示 redis Master节点 6379端口,R1 表示 redis replication 节点 6379端口,S1 表示哨兵1(Master节点上),S2 表示哨兵2(Replication节点上/Slave节点上),如下图:
    在这里插入图片描述

    情况1:M1 6379端口宕机了,但是M1所在机器整个机器没有宕机
    处理方式: s1和s2两个哨兵只要有一个(超过半数)认为你宕机了就切换了,并且会选举出一个哨兵去执行故障,但是这个时候也需要大多数哨兵都是运行的。M1宕机了,S1没挂那其实是OK的,

    情况2:M1 所在机器整个机器都挂了,就是M1 和 S1都挂了
    处理方式:哨兵就只剩下S2一个了,没有哨兵去允许故障转移了,虽然另外一个机器上还有R1,但是故障转移就是不执行。

    经典的哨兵集群是这样的,三个机器,如下图:
    在这里插入图片描述
    情况:M1所在的机器挂了,M1 S1 都挂了
    处理方式:哨兵还有两个,S2 和 S3,两个哨兵一看他不是挂了嘛,那我们就选举一个出来执行故障转移不就好了。

    三、Sentinel实践

    3.1 Sentinel配置

    第一步,两种从节点的 redis.conf 配置上主节点(主从结构完成):

    vi redis.conf
    replicaof 主节点ip(192.168.100.138) 6379 
    cat redis.conf | grep replicaof
    
    • 1
    • 2
    • 3

    注意:对于任何一个从节点,redis-cli 执行 slaveof no one 就可以脱离主从结构了

    第二步,三个节点修改 sentinel.conf 配置文件(在redis.conf同级目录下)

    vi sentinel.conf 内容如下

    daemonize yes
    port 26379
    protected-mode no
    dir "/root/redis-6.0.9/sentinel-tmp"
    sentinel monitor redis-master 192.168.100.138 6379 2
    sentinel down-after-milliseconds redis-master 30000
    sentinel failover-timeout redis-master 180000
    sentinel parallel-syncs redis-master 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后执行 mkdir /root/redis-6.0.9/sentinel-tmp

    sentinel.conf 也并不是要一定和 redis.conf 在同级目录下,只要启动 redis-sentinel 的时候不要指定错了就好了

    启动三个redis-server 和 三个 redis-sentinel ,如下(三个机器都要执行)

    # 启动中使用 redis.conf 文件 
    ./src/redis-server redis.conf
    # 启动中使用 sentinel.conf 文件
    ./src/redis-sentinel sentinel.conf
    
    • 1
    • 2
    • 3
    • 4

    启动之后要测试自己的是否搭建好了,验证包括两个方面。

    主从结构验证:
    测试方法1:info命令 redis集群的任何一个节点,都可以在redis-cli中执行 info replication
    测试方法2:在主节点set,然后在两个从节点可以get得到

    sentinel生效验证:主节点宕机之后选主(保证高可用),新的节点加入后作为从节点

    3.2 实践:Sentinel基本使用

    3.2.1 实践:Sentinel搭建

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    3.2.2 实践:主节点宕机之后的选主过程(Sentinel保证高可用)

    演示sentinel主持下的选主过程 (主节点上 ./redis-cli --raw 执行里面 shutdown 将主节点挂掉)

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    主节点(192.168.100.138) 上 ./redis-cli --raw 执行里面 shutdown 将主节点挂掉,仅仅是是去掉停止了 主节点上 redis-server,没有停止主节点上的 redis-sentinel

    3.2.3 实践:新节点加入之后成为从节点

    演示sentinel主持下的从节点加入过程 (刚刚挂掉的主节点再次启动 ./src/redis-server redis.conf)
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    3.3 Sentinel连接

    Java程序连接:有了 sentinel 之后,直接连接sentinel就可以操作redis集群,不用连接实际的redis节点 6379.

    因为 sentinel 每个节点都会监控整个redis集群,而且sentinel节点之间还会互相监控,sentinel各个节点之间是平等个关系,redis各个节点节点之间是主从关系。

    最后,其实只要连接一个 sentinel 节点就好了,根本不需要连接三个 sentinel 节点,因为一个sentinel节点就已经可以监控 整个 redis 集群了。

    3.3.1 java程序连接Sentinel

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    3.3.2 springboot工程连接Sentinel

    <dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    四、Sentinel的不足

    问题1:Sentinel支持的主从切换过程中会丢失数据,因为只有一个master,slave不可能完整的保证offset和master相同。

    问题2:只能单点写,没有解决大数据量,内存存放不下,水平扩容的问题。如果数据量非常大,这时候就要对redis的数据分节点存储了。这个时候需要多个 master-slave 的group,将不同的数据分布到不同的group中。

    在这里插入图片描述

    问题来了,数据如何分片存储?读取的时候如何路由?

    五、尾声

    Sentinel最重要的的就是故障转移,主节点宕机之后的选主功能,包括:

    问题1:什么情况下要选主?
    回答1:当主节点挂掉之后要选主。当主挂掉时,在从节点中根据一定策略选出新主,并调整其他从 slaveof 到新主。

    问题2:如何选主,到底选哪个slave从节点作为master主节点?
    回答2:Redis选主的策略简单来说有三个:
    (1)相同条件下,slave 的 priority 设置的越小,优先级越高;
    (2)相同条件下,slave 复制的数据越多,优先级越高;
    (3)相同条件下,slave 的 进程id 越小,优先级越高;

    Redis集群实现Sentinel哨兵应对高可用,完成了。

  • 相关阅读:
    [Java] Lock(锁)的tryLock失败是否需要unlock?
    【Django】RESTful API接口设计风格
    WireShark 实践操作
    基于springboot的支教系统-计算机毕业设计源码
    Leetcode周赛368补题(3 / 3)
    云原生之旅 - 13)基于 Github Action 的自动化流水线
    SQL Server重置自增序列初始值
    Django使用正则表达式
    JAVA基础总结
    构造函数练习
  • 原文地址:https://blog.csdn.net/qq_36963950/article/details/126810432