• Redis的主从复制


    主从复制的定义

    主从复制:主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master主服务器以写为主,Slave从服务器以读为主。如下图:

    在这里插入图片描述


    主从复制的优缺点

    两个优势:

    • 读写分离

    如果只有一台服务器,读和写操作都在一台服务器上进行,这台服务器的压力就会很大。而使用主从复制可以达到读写分离效果,写操作都在master主服务器进行,写操作进行完成之后,把内容复制到它的从服务器去;读操作都在slave从服务器进行。

    • 容灾快速恢复

    如果主服务器中进行写操作之后,复制到了从服务器(从服务器一般有多台),如果第一台从服务器在读的过程中突然挂掉,就会切换到另外一台从服务器进行读操作,此即为容灾快速恢复。

    一个缺陷:

    主从复制存在的缺点是复制延时:
    由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。


    注意:

    “领导多了,员工不知道听谁的。”—因此:主从一般都为一主多从。主服务器只能有一个。


    搭建主从复制环境(一主两从)

    在一台服务器上,搭建一主两从的模拟环境。(因为是一台服务器,因此要保证三者的端口不同)操作如下:

    ①为了方便先创建一个myRedis的文件夹
    在这里插入图片描述
    ②复制Redis.conf文件到此文件夹
    在这里插入图片描述

    ③配置一主两从,创建三个配置文件:redis6379.conf、redis6380.conf、redis6381.conf(保证三者端口不同)
    在这里插入图片描述

    由于redis配置文件redis.conf中有公共配置部分,所以在三个新建的配置文件中只需要引入公共配置(使用include),其他不同的地方(进程号pid、端口号、rdb持久化文件的名称)进行单独配置。
    在这里插入图片描述
    配置完成后 :wq 保存退出
    在这里插入图片描述

    ⑤启动三台Redis服务器
    在这里插入图片描述
    注意:如果本机的redis服务器也为6379,就会和此处用于演示的redis6379服务器冲突,可以使用kill命令先关闭原有的reis进程,再开启我们自定义的myredis目录下用于演示的redis6379服务器。


    • redis-server redis6379.conf:根据配置文件启动相应的Redis服务器。 如下图:
      在这里插入图片描述

    • redis-cli -p 端口号:通过端口号连接Redis服务器。 如下图:
      在这里插入图片描述

    • info replication:打印主从复制的相关信息,用来查看运行情况。 如下图:
      注意:此命令需要连上Redis后使用。 如下图:
      在这里插入图片描述

    目前虽然启动了三台Redis服务器,但此时并没有主从的效果。想要实现主从,还需要在目标从服务器使用slaveof命令

    • slaveof ip port :使当前服务器临时成为某个实例的从服务器(重启Redis服务器后会失效)

    要想设置6379为主机,6380、6381为从机:需要在从机上使用slaveof命令进行配置。(小弟认大哥的过程,小弟要主动)

    在这里插入图片描述

    一主两从效果搭建完成。如下图:
    在这里插入图片描述

    搭建好一主二从之后,进行测试。

    在主服务器中进行写操作,可以在从服务器中成功读到。如下图:

    在这里插入图片描述


    特殊情形一:
    一主(6379)二从(6380、6381)。如果某一台从服务器(如6380)挂掉(可以使用shutdown命令)了,还会剩一个6381从服务器正常运行。此时在主服务器(6379)中添加数据,如下图:
    在这里插入图片描述
    正常运行的从服务器(6381)可以读到数据,如下图:
    在这里插入图片描述
    若此时把挂掉的6380从服务器再次启动起来(redis-server redis6380.conf),连接Redis(redis-cli -p 6380),查看6380Redis服务器状态信息(info replication)会出现什么效果?如下图:
    在这里插入图片描述
    此时若想让6380Redis服务器继续做6379主服务器的从服务器可以使用slaveof命令,如下图:
    在这里插入图片描述
    此时查看6380Redis服务器中的key值信息,如下图:
    在这里插入图片描述

    也就是说,如果主机在从服务器挂掉之后修改了数据,再把挂掉的服务器 **作为主机的从服务器重新启动** ,主机中的最新的数据依然会被复制到从服务器中去。

    就好比 “只要小弟(从服务器)做大哥(主服务器)的人,大哥有什么资源都会毫无保留地和小弟分享。”


    特殊情形二:
    如果6379主服务器挂掉了,如下图:
    在这里插入图片描述
    查看从服务器(6380、6381)的状态信息(info replication),如下图:
    在这里插入图片描述
    在这里插入图片描述
    查看后发现,从服务器的角色依然为从服务器,并没有“篡位”变为主服务器。
    再次对6379主服务器进行启动(redis-server redis6379.conf),连接(redis-cli -p 6379),查看信息(info replication)。如下图:
    在这里插入图片描述
    在这里插入图片描述

    也就是说,即使6379主服务器挂掉了,6380和6381两个服务器的角色依然是从服务器,而且认为主服务器依然为6379。(大哥永远是大哥)

    就好比,“即使大哥挂掉了,小弟依然把他当作大哥,并不会上位。


    主从复制原理

    在这里插入图片描述

    • 从服务器连接到主服务器后会向主服务器发送一个sync命令,告诉主服务器现在可以做数据同步了
    • 主服务器接收到从服务器发送来的消息后,把当前主服务器中的数据先进行持久化(把数据放到rdb文件中去),把rdb文件发送给从服务器,从服务器拿到rdb文件之后进行数据读取,完成复制
    • 每次主服务器进行写操作之后,主动和从服务器进行数据同步

    从服务器只在第一次主动请求同步,其他大部分过程都是主服务器发起的。

    了解两个概念:

    • 全量复制: 从服务器在接收到数据库文件数据后,将其存盘**并加载到内存中。
    • 增量复制: 主服务器继续将 新的所有收集到的修改命令 依次传给slave,完成同步。

    只要是重新连接主服务器,就会自动进行一次完全同步(全量复制)


    薪火相传

    上一个Slave从服务器可以是下一个slave从服务器的主服务器。Slave从服务器同样可以接收其他slave从服务器(可以是多个)的连接和同步请求,那么该slave从服务器作为了链条中下一个slave从服务器的主服务器,可以有效减轻master的写压力,去中心化降低风险。类似数据结构中的树形结构,等级森严。

    这种薪火相传的模式肯定会有一个缺点:如果某一个从服务器挂掉了,它下面的服务器就不能再进行数据同步。


    反客为主

    当一个主服务器挂掉后,手动把后面的从服务器升级为主服务器,其后面的从服务器不用做任何修改。

    效果演示:
    ①让6379主服务器挂掉(shutdown)
    在这里插入图片描述

    ②查看6381从服务器的状态信息(info replication)
    在这里插入图片描述

    ③手动让6380从服务器“上位”,变为主服务器(slaveof no one)
    在这里插入图片描述
    ④查看6380服务器的状态信息
    在这里插入图片描述
    slaveof no one:把从机变为主机

    此即为反客为主

    这种 反客为主模式会有一个缺点:需要手动完成。 如果服务器大半夜挂掉了,还需要我们大半夜爬起来去手动切换,很不方便。

    能不能让这个过程自动完成?实现主服务器如果挂掉了,从服务器立马挑起大梁,晋升为主服务器。

    此即为接下来要介绍的哨兵模式实现的效果。


    哨兵模式

    在这里插入图片描述

    哨兵模式即为反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。

    演示:
    调整到一主二从状态进行演示:
    在这里插入图片描述

    配置哨兵(sentinel):
    在这里插入图片描述

    • ①在自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错
      在这里插入图片描述

    • ②写入内容:
      sentinel monitor mymaster 服务器ip 端口号 1:其中mymaster为监控对象起的服务器名称;最后的参数表示至少有多少个哨兵同意迁移的数量。(此处最后参数为1则表示只要有一个哨兵同意就能进行切换)
      在这里插入图片描述

    • ③启动哨兵(redis-sentinel /myredis/sentinel.conf )
      在这里插入图片描述
      最终切换为主机的服务器是从被监视服务器的从服务器中取。

    • ④关闭6379主服务器
      在这里插入图片描述

    • ⑤哨兵监控窗口信息如下:
      在这里插入图片描述

    • ⑥查看6381服务器状态
      在这里插入图片描述
      此时连接的从服务器(connected_slaves)只有一个6380,因为6379还没有重新启动。

    • ⑦查看6380服务器状态
      在这里插入图片描述

    • ⑧重启6379服务器,并查看状态信息
      在这里插入图片描述
      在这里插入图片描述


    总结哨兵模式:
    在这里插入图片描述

    ①选择优先级高的从服务器作为主服务器(值越小,优先级越高)

    在redis的配置文件中都会有相应的优先级(默认值为100),如下图:在这里插入图片描述

    ②如果优先级相同,选择偏移量最大的从服务器作为主服务器

    即两台从服务器中,和主机的的数据同步程度最高的从服务器,偏移量较大,更适合转化为主服务器。

    ③如果优先级和偏移量都相同,选择runid最小的从服务器作为主服务器

    每个redis实例启动后都会随机生成一个40位的runid。选择runid最小的


    JedisSentinelPool连接池

    想使用Java代码实现主从操作特点,可以使用JedisSentinelPool连接池。

    JedisSentinelPool模板如下:

        private static JedisSentinelPool jedisSentinelPool = null;
    
        public static Jedis getJedisFromSentinel() {
            if (jedisSentinelPool == null) {
                Set<String> sentinelSet = new HashSet<>();
                sentinelSet.add("47.116.4.200:26379");  //服务器ip:哨兵端口号(默认26379)
    
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                jedisPoolConfig.setMaxTotal(10); //最大可用连接数
                jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
                jedisPoolConfig.setMinIdle(5); //最小闲置连接数
                jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
                jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
                jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong
    
                jedisSentinelPool = new JedisSentinelPool("mymaster", sentinelSet, jedisPoolConfig, "******");  //如果Redis服务器配置了密码,需要在最后一个参数写入密码
                return jedisSentinelPool.getResource();
            } else {
                return jedisSentinelPool.getResource();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:想要使用如上哨兵模式连接池,需要在服务器上配置26379端口的安全组或使用宝塔面板放行26379端口、还要确保哨兵服务器的正常运行状态。否则上述程序无法运行成功。

  • 相关阅读:
    全屋智能:鱼很大,但水更深
    2-分类问题 SVM 核函数
    3道软件测试面试题,能全答对的人不到10%!你会几个?
    【JAVA】Servlet
    腾讯JAVA后端秋招面试总结
    php 安装rabbitmq:如何使用 PHP 安装 RabbitMQ?
    实在智能应邀出席中国移动科技工作者论坛,分享基于大模型+Agent智能体的“企业大脑”
    Elastic换帅,Kunlkarni接替Banon成为新任CEO
    深兰科技成功入选《2023年度国家知识产权优势企业名单》
    三大O(nlogn)算法分析
  • 原文地址:https://blog.csdn.net/qq_46370017/article/details/126327979