Redis主从复制

19 阅读7分钟

Redis主从复制

第一节 什么是主从复制

主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

第二节 主从复制的作用

  • 读写分离,性能扩展
  • 容灾快速恢复

第三节 主从复制具体操作

(1)实现思路

  • 1 一个redis服务作为主机,主要负责写操作
  • 2 两个redis服务作为从机,主要负责读操作
  • 3 从机自动从主机同步数据下来
  • 4 从机主动找主机,而主机不会找从机
  • 5 正常来说主机和从机应该在不同的IP上开启redis服务,我们为了快速模拟,可以在一台机器上模拟出三个redis服务即可

(2) 一台机器上启动多个redis服务

使用redis-server启动服务时,要以来redis.conf配置文件.那么我们可以准备三个redis.conf文件,用来配置三个不同的服务,启动三次分别以来三个不同的服务即可

(3)新建三个redis配置文件

用于定义每个服务的专属配置

  • 新建redis6379.conf

    关闭aof功能

include /root/myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

  • 含义介绍
include /root/myredis/redis.conf # 引入共同的配置
pidfile /var/run/redis_6379.pid # 使用独立的进程文件
port 6379 # 设置当前服务的端口号
dbfilename dump6379.rdb # 使用独立的RDB持久化文件  暂时不适用AOP持久化
  • 新建redis6380.conf

  • 新建redis6381.conf

  • 在redis6381中多添加一个配置,设置从机的优先级,值越小,优先级越高,用于选举主机时使用。默认100
replica-priority 10  0-100 哨兵模式下,选举的时候,有用! 谁的值小谁优先级高!谁当主机!!

(4)启动三个服务

(5)查看启动服务进程

(6)使用info replication查看主从相关信息

  • 连接redis,使用:redis-cli -p 端口号
  • 执行 info replication查看信息

(7) 配置主从机器

  • 配从不配主,是让从机主动去找主机
  • 在6380 和6381的机器上执行如下命令
slaveof 127.0.0.1 6379
  • 执行完毕再次查看主从配置信息

(8)测试主从读写操作

  • 主机上写入数据OK
  • 在从机上写数据报错

  • 主机宕机,重启即可恢复主从状态,无需其他操作
  • 从机宕机,重启后需要重新执行 slaveof 127.0.0.1 6379 才能恢复
  • 从机可以在配置文件中写入slaveof 127.0.0.1 6379 ,这样重启无需手动输入slaveof 127.0.0.1 6379就可以恢复从机状态

第四节 主从复制原理

  • Slave启动成功连接到master后会发送一个sync命令
  • Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
  • 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  • 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
  • 但是只要是重新连接master,一次全量同步(全量复制)将被自动执行

第五节 主从复制三种模式

  1. 第一种 一主二仆
  • 问题1: 切入点问题,slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的k1,k2,k3是否也可以复制?[全量复制 第一次]
  • 问题2 :从机是否可以写?set可否? [不可以]
  • 问题3:主机shutdown后情况如何?从机是上位还是原地待命? [从机还是小弟]
  • 问题4:主机又回来了后,主机新增记录,从机还能否顺利复制? [可以]
  • 问题5:其中一台从机down后情况如何?依照原有它能跟上大部队吗(还会自动变为从机吗?)? [15 断了在连一下slaveof ]

  1. 第二种 薪火相传
上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。用 slaveof  <ip><port>
中途变更转向:会清除之前的数据,重新建立拷贝最新的,风险是一旦某个slave宕机,后面的slave都没法备份,主机挂了,从机还是从机,无法写数据了

  1. 第三种 反客为主
  • 当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。用 slaveof no one 将从机变为主机。

第六节 哨兵模式

6.1 哨兵模式简介

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

6.2 哨兵模式的使用步骤

(1)第一步: 设置简单的一主二仆

(2)第二步: 为哨兵模式准备配置文件
  • 在/root/myredis 目录下新建sentinel.conf 配置文件中放入如下内容
sentinel monitor mymaster 127.0.0.1 6379 1
  • 其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量。
  • 注意: 此处的ip地址可以测试127系列,也可以是真实系列,建议配置成真实系列!
(3)第三步: 启动哨兵
  • 运行/usr/local/bin 下 redis-sentinel 命令,执行/root/myredis/sentinel.conf配置文件
redis-sentinel /root/myredis/sentinel.conf
  • redis做压测可以用自带的redis-benchmark工具

6.3 哨兵模式的操作演示

(1)主机宕机演示
当主机宕机,会从从机中选择一个作为新的主机,根据优先级slave-properity, 原主机重启后会成为从机

(2)复制延时
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
(3)故障恢复
  • 优先级在redis.conf中默认:replica-priority 100,值越小优先级越高

  • 偏移量是指获得原主机数据最全的 在 Redis 中,复制偏移量(Replication Offset)是用于表示从节点与主节点之间数据同步的进度的一个重要指标。它是一个递增的整数值,用于记录从节点复制主节点数据时已经复制的字节数量。

    复制偏移量越高,说明从节点复制主节点的数据越完整,数据同步得越快。

  • 每个redis实例启动后都会随机生成一个40位的runid

第七节 RedisTemplate连接哨兵模式

7.1 导入依赖

<dependencies>
    <!-- 基本启动 starter - autoconfigure - 142配置类  web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- 连接池-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>

</dependencies>

7.2 哨兵配置

spring:
  data:
    redis:
      client-type: lettuce
      lettuce:
        pool:
          enabled: true
          max-active: 8
          max-idle: 5
          max-wait: 100
      sentinel:
        # 哨兵名称
        master: mymaster
        # 哨兵地址,集群继续配置多个
        nodes:
          - 192.168.6.100:26379

7.3 读写策略配置

@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer =
            							new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }


    /**
     * 配置主和从节点访问策略
     * - MASTER:从主节点读取
     * - MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica
     * - REPLICA:从slave(replica)节点读取
     * - REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取master
     * @return
     */
    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
        //设置访问策略值
        return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
    }
}