七、redis复制

参与复制的redis节点分为master和slave,也就是主从,默认情况下都为master节点。复制过程,数据是单向的,只能从主节点复制到从节点。

建立复制和断开连接

建立复制的方式有三种:

  1. 在配置文件中加入 slaveof {host} {port},表示将{host:port}对应的节点作为自己的主节点。
  2. 在redis-server启动命令中加入–slaveof参数
  3. 在客户端中使用命令:slaveof

复制的过程是一个异步过程,在执行命令后,只保存master节点信息并立即返回,后续复制过程异步执行。

建立复制成功后,可以分别在master和slave节点上查看状态

1
2
3
4
5
6
7
8
9
10
11
12
13
localhost:6379> info replication
# Replication
role:master # 表明自己是主节点,对应的slave是6378
connected_slaves:1
slave0:ip=127.0.0.1,port=6378,state=online,offset=1079997,lag=0
master_replid:d67a40111ca08c6871fcc411632b16e368fbe54f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1079997
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:31422
repl_backlog_histlen:1048576
  • 断开连接,slaveof no one ,注意断开连接,只是不再复制master的数据,但之前的数据还保存

复制过程

  1. 保存主节点信息

  2. 主从节点建立socket连接,通过定时任务维护复制逻辑,发现新的主节点后,会尝试与该节点建立网络连接(专门开启一个端口)。

  3. 发送ping命令,从节点发送ping请求通信,如果失败,会断开socket连接,下次定时任务重新开启

  4. 权限验证,如果主节点配置了密码,从节点需要配置masterauth参数,否则重新发起复制流程。

  5. 同步数据集,成功后,进入首次复制流程,主节点采用复制命令psync(sync是旧版本,这里不做讲解)

    • 全量复制: 在初次复制场景,会一次性把所有数据发给从节点,是一个非常耗时的操作。

      1. 从节点发送psync-1命令,代表没有偏移量

      2. 主节点发送+FULLRESYNC,以及当前偏移量和server id,从节点保存该信息

      3. 主节点会首先执行bgsave,保存当前的数据到RDB文件

      4. 发送到从节点上(网络开销较大)可以看日志MASTER<->SLAVE,如果超过时间(默认60s),则会复制失败

      5. 从节点接受到数据后保存,并直接作为本节点的数据文件,然后清空现有数据并加载数据

      6. 从节点如果开启了AOF,则会立即bgrewriteaof操作,重新备份aof文件。

    • 部分同步: 用于处理由于网络或其他原因导致的数据丢失(采用offset机制),补发丢失数据,另外主节点和从节点同步时,也会把命令写入复制积压缓冲区,如果发生了断连,等重新连接后,可以从复制积压缓冲区中同步。

    • 复制缓冲区: 在全量复制的过程中,master节点还会收到来自其他客户端的请求,这一部分数据会保存在复制缓冲区当中,当RDB发送成功之后,会把缓冲区内的数据发给从节点,如果缓冲区内的数据溢出,也就是同步期间master接受到的命令过多,会导致同步失败,重新开始

    • 复制积压缓冲区: 是在master和slave节点追加同步过程中,发生了网络断开,从节点再次连接后,会从复制积压缓冲区里同步,如果超过了复制积压缓冲区的数量(会根据从节点发过来的offset在复制缓冲区里查找),则会触发全量复制。
      psync过程

  6. 命令持续复制,当前的数据同步到从节点后,后面就是持续同步的过程,也就是只同步新增的命令

每个redis节点启动后都会重新分配一个唯一的ID,从节点是根据ID来识别master的,所以在ID变化后(master重启)从节点将做一次全量复制。
如何在不改边id的情况重启?可以使用debug-reload命令重新加载(会阻塞)

授权

默认情况下,我们没有设置密码,也就是任意机器都可以复制我们的信息,为了增加安全,master节点通常会设置密码,来保证安全。

  • 设置本机密码:CONFIG set requirepass password (也可在配置文件中配置)
  • 客户端连接:启动客户端后,auth password
  • slave连接:config set masterauth password (否则日志会一直报错)

一般如果配置成从节点,可以使用slave-read-only=yes,这样可以避免修改从节点导致的主从数据不一致问题

传输延迟

  1. redis提供了repl-disable-tcp-nodelay参数,当关闭时,无论命令数据大小都会及时的发给从节点,这样延迟会减小,但会增加带宽,如果开启,则会将小的数据合并再发送

部署方案

  • 主从结构
  • 树状结构
  • 读写分离(复制数据延迟,读到过期数据)

规避全量复制

全量复制是一个很耗资源的操作,包括内存、cpu、网络io等。应该尽量规避

  • 第一次建立复制:应该尽量在业务量少的情况进行
  • 节点运行ID不匹配:当主节点因故障重启,它的id会发生改变,这个时候会进行全量复制。这种情况应该从架构上规避,比如采用集群模式或者哨兵模式。
  • 复制积压缓冲区不足:对于大流量场景,应需估计网络波动时长,增大积压缓冲区。
  • 复制风暴:一般发生在一个master节点挂载多个slave节点的情况。可以采用树状结构