• Redis与分布式:哨兵模式


    前面我们讲解了Redis实现主从复制的一些基本操作,那么我们接着来看哨兵模式。

    经过之前的学习,我们发现,实际上最关键的还是主节点,因为一旦主节点出现问题,那么整个主从系统将无法写入,因此,我们得想一个办法,处理一下主节点故障的情况。实际上我们可以参考之前的服务治理模式,比如Nacos和Eureka,所有的服务都会被实时监控,那么只要出现问题,肯定是可以及时发现的,并且能够采取响应的补救措施,这就是我们即将介绍的哨兵:

    注意这里的哨兵不是我们之前学习SpringCloud Alibaba的那个,是专用于Redis的。哨兵会对所有的节点进行监控,如果发现主节点出现问题,那么会立即让从节点进行投票,选举一个新的主节点出来,这样就不会由于主节点的故障导致整个系统不可写(注意要实现这样的功能最小的系统必须是一主一从,再小的话就没有意义了)

    那么怎么启动一个哨兵呢?我们只需要稍微修改一下配置文件即可,这里直接删除全部内容,添加:

    sentinel monitor lbwnb 127.0.0.1 6001 1

    其中第一个和第二个是固定,第三个是为监控对象名称,随意,后面就是主节点的相关信息,包括IP地址和端口,最后一个1我们暂时先不说,然后我们使用此配置文件启动服务器,可以看到启动后:

    可以看到以哨兵模式启动后,会自动监控主节点,然后还会显示那些节点是作为从节点存在的。

    现在我们直接把主节点关闭,看看会发生什么事情:

    可以看到从节点还是正常的在报错,一开始的时候不会直接重新进行选举而是继续尝试重连(因为有可能只是网络小卡一下,没必要这么敏感),但是我们发现,经过一段时间之后,依然无法连接,哨兵输出了以下内容:

    可以看到哨兵发现主节点已经有一段时间不可用了,那么就会开始进行重新选举,6003节点被选为了新的主节点,并且之前的主节点6001变成了新的主节点的从节点:

    当我们再次启动6001时,会发现,它自动变成了6003的从节点,并且会将数据同步过来:

    那么,这个选举规则是怎样的呢?是在所有的从节点中随机选取还是遵循某种规则呢?

    1. 首先会根据优先级进行选择,可以在配置文件中进行配置,添加replica-priority配置项(默认是100),越小表示优先级越高。
    1. 如果优先级一样,那就选择偏移量最大的
    1. 要是还选不出来,那就选择runid(启动时随机生成的)最小的。

    要是哨兵也挂了咋办?没事,咱们可以多安排几个哨兵,只需要把哨兵的配置复制一下,然后修改端口,这样就可以同时启动多个哨兵了,我们启动3个哨兵(一主二从三哨兵),这里我们吧最后一个值改为2

    sentinel monitor lbwnb 192.168.0.8 6001 2

    这个值实际上代表的是当有几个哨兵认为主节点挂掉时,就判断主节点真的挂掉了

    现在我们把6001节点挂掉,看看这三个哨兵会怎么样:

    可以看到都显示将master切换为6002节点了。

    那么,在哨兵重新选举新的主节点之后,我们Java中的Redis的客户端怎么感知到呢?我们来看看,首先还是导入依赖:

    1. <dependencies>
    2. <dependency>
    3. <groupId>redis.clientsgroupId>
    4. <artifactId>jedisartifactId>
    5. <version>4.2.1version>
    6. dependency>
    7. dependencies>
    1. public class Main {
    2. public static void main(String[] args) {
    3. //这里我们直接使用JedisSentinelPool来获取Master节点
    4. //需要把三个哨兵的地址都填入
    5. try (JedisSentinelPool pool = new JedisSentinelPool("lbwnb",
    6. new HashSet<>(Arrays.asList("192.168.0.8:26741", "192.168.0.8:26740", "192.168.0.8:26739")))) {
    7. Jedis jedis = pool.getResource(); //直接询问并得到Jedis对象,这就是连接的Master节点
    8. jedis.set("test", "114514"); //直接写入即可,实际上就是向Master节点写入
    9. Jedis jedis2 = pool.getResource(); //再次获取
    10. System.out.println(jedis2.get("test")); //读取操作
    11. } catch (Exception e) {
    12. e.printStackTrace();
    13. }
    14. }
    15. }

    这样,Jedis对象就可以通过哨兵来获取,当Master节点更新后,也能得到最新的。

  • 相关阅读:
    SAS|画图
    基于级联广义积分器(CGI)的谐波信号提取MATLAB仿真
    数据仓库与数据湖的区别以及数据入湖方式
    怎么将Linux上的文件上传到github上
    判断矩形与矩形、圆、三角形的相交问题
    doris手动添加分区自动消失的问题
    渗透测试-sql注入漏洞
    java计算机毕业设计进出货管理系统源码+mysql数据库+系统+lw文档+部署
    虚拟机和开发板互Ping问题
    计算机组成原理习题课第三章-4(唐朔飞)
  • 原文地址:https://blog.csdn.net/Leon_Jinhai_Sun/article/details/126081452