Redis主从复制

  • Redis主从复制的概念

    img

    主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower) ; 数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。

    和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步增量同步

    默认情况下,每台redis服务器都是主节点,一个主节点可以有多个从节点,一个从节点只能有一个主节点。单台Redis服务器内存使用不超过20G。

    ##主从复制的作用

    1. 读写分离主节点写,从节点读,提高服务器的读写负载能力
    2. 数据冗余︰主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
    3. 故障恢复︰当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 ; 实际上是一种服务的冗余。
    4. 负载均衡︰在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载 ; 尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
    5. 高可用(集群)基石︰除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

    环境配置

    只用配置从机,因为默认自己是主机。配置不同的配置文件,只需要在从机上配置即可,认主人。

    • 配置文件

      redis-6379.conf redis-6380.conf redis-6381.conf

      1
      2
      3
      4
      5
      port 6379#6380 6381
      daemonize yes
      pidfile /var/run/redis_6379.pid
      logfile "6379.log" #6380.log 6381.log
      dbfilename dump6379.rdb #dump6380.rdb dump6381.rdb
    • 从机

      1
      slaveof 127.0.0.1 6379
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      [yio@master src]$ ./redis-cli -p 6381
      127.0.0.1:6381> info replication
      # Replication
      role:master
      connected_slaves:0
      master_failover_state:no-failover
      master_replid:8d2806a006dbbe74942d404121a6ebb77be50dce
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:0
      second_repl_offset:-1
      repl_backlog_active:0
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:0
      repl_backlog_histlen:0
      127.0.0.1:6381> slaveof 127.0.0.1 6379
      OK
      127.0.0.1:6381> info replication
      # Replication
      role:slave
      master_host:127.0.0.1
      master_port:6379
      master_link_status:up
      master_last_io_seconds_ago:6
      master_sync_in_progress:0
      slave_read_repl_offset:42
      slave_repl_offset:42
      slave_priority:100
      slave_read_only:1
      replica_announced:1
      connected_slaves:0
      master_failover_state:no-failover
      master_replid:b176050aa3205b4eec01db91306e73f0796dbd2b
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:42
      second_repl_offset:-1
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:15
      repl_backlog_histlen:28
    • 主机

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      127.0.0.1:6379> info replication
      # Replication
      role:master
      connected_slaves:0
      master_failover_state:no-failover
      master_replid:2779994fcc01f1aac5b578702c16f8c31c05c038
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:0
      second_repl_offset:-1
      repl_backlog_active:0
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:0
      repl_backlog_histlen:0
      127.0.0.1:6379> info replication
      # Replication
      role:master
      connected_slaves:2
      slave0:ip=127.0.0.1,port=6380,state=online,offset=14,lag=0
      slave1:ip=127.0.0.1,port=6381,state=wait_bgsave,offset=0,lag=0
      master_failover_state:no-failover
      master_replid:b176050aa3205b4eec01db91306e73f0796dbd2b
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:14
      second_repl_offset:-1
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:1
      repl_backlog_histlen:14
    • 以上只是命令式的暂时配置,持久配置需要在配置文件里面进行。

      1
      2
      replicaof <masterip> <masterport>
      masterauth <master-password> #主机密码
    • 主机写,从机读。主机内容保存到从机。

    复制原理

    全量复制

    全量同步

    Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

    • 从服务器连接主服务器,发送SYNC命令;
    • 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
    • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
    • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
    • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
    • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

    img

    ###增量复制

    Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。

    增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令

    ###Redis主从同步策略

    主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

    注意点:如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

    链式

    1
    2
    3
    4
    A -> B: A是B的master
    note right of B: B是Slave
    B -> C: B是C的master(相对)
    note right of C: C是Slave

    上图中B和C都是从机的,只有A是主机

    故障

    • 从节点故障时,只用给连在上面的客户端连接别的从节点即可
    • 主节点故障时,我们要使用客户端在某个从节点使用salveof no one,使该从节点变成主节点,之后在其他的从节点执行salveof new master,连接新的主节点,同时也要迁移原从节点只读操作
    • 哨兵系统可以自动

    Redis哨兵(sentinel)模式

    redis的哨兵模式,就是用于在一主多从的集群环境下,如果主服务器宕机了,它会自动的将从服务器中的一台设为新的master,并且将其余的slave的配置文件自动修改,这样就切换出一套新的主从服务,不需要人工干预,且不会影响服务的使用。

    哨兵是一个独立于主从服务之外的服务,它也是一个集群服务,也就是说一个系统会使用过个哨兵进行监控,各个哨兵之间也会彼此监控,形成监控网络。哨兵实例会不断给主服务器发送Ping命令,主服务器在收到命令后,返回一个有效回复,这样哨兵实例认为服务器是正常的。

    img

    主观下线

    如果,哨兵一号在指定的时间内(可配置)没有收到主机的回复消息,就会认为它已经下线,即使客观上它并没有下线,可能只是因为某些原因导致给哨兵一号的回复没有抵达。这就被叫做主观下线SDOWN。

    客观下线

    哨兵二号也发送了Ping命令,同样也没有收到回复,哨兵二号也会将主服务器标记为SDOWN。这个时候,3个哨兵中有2个哨兵上报了SDOWN,哨兵们在彼此交流之后,认为已经有足够数量(这里的足够数量是可配置的,一般是哨兵个数的一半加1,比如3个哨兵则就设置为2)的实例证明该服务已经不可用,因此,哨兵实例会将该服务器标记为客观下线ODOWN。

    当哨兵实例将服务标记为客观下线时,会进行一次选举。在剩下的从服务器实例中,选出一个作为主节点,并同时修改其余从服务器的配置文件,将新的主节点作为数据同步的来源,然后重新启动服务,完成切换。

    配置

    1. 哨兵配置文件 sentinel.conf

      1
      2
      3
      #sentinel monitor 被监视的名称 host port 1
      sentinel monitor myredis 127.0.0.1 6379 1
      # 1 表示主机挂了之后,slave投票看谁接替成为主机,票数最多的成为主机
    2. 启动哨兵

      1
      redis-sentinel sentinel.conf

    SpringBoot配置一主多从+哨兵

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    redis:
    host: 127.0.0.1
    port: 6379
    password:
    #连接超时
    timeout: 10s
    database: 16
    sentinnel:
    master: mymaster
    nodes: #哨兵ip:端口

    参考:

    作者: Meow Mii

    本文链接: https://blog.yiochin.top/p/c328eac5.html

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议,转载请注明出处!


    📝 Comment