redis复制过程演变

Redis的主从复制主要经历以下的几个阶段:

  1. 2.8版本以下—-sync
  2. 2.8-4.0版本—-psync
  3. 4.0版本+ —-psync2

下面我就来简单的讲讲Redis主从复制的演变过程。

Redis主从复制过程

  • 客户端发送slaveof命令给Redis实例
  • 准备阶段函数为replicationSetMaster,这个函数主要会做一些复制之前的数据和状态清理工作。
  • 更新server.master
  • 将实例状态修改为REPL_STATE_CONNECT

    Redis每秒会调用一次replicationCron定时任务。根据Redis当前所处状态来决定下一步操作。
  • 当Redis状态为REPL_STATE_CONNECT时会调用connectWithMaster创建连接master事件。该函数会将Redis状态修改为REPL_STATE_CONNECTING
  • 接下来进行心跳检查、权限校验等操作
  • master接收到slave的复制命令后,就会触发一次rdb全备,并记录下全备期间的命令。
  • master将全备文件发送给slave后,将增量命令发送给slave。
  • 心跳维持和持续复制

主从复制的演变

在2.8之前的版本中,如果由于网络等原因导致主从复制断开。那么就会将从节点状态修改为REPL_STATE_CONNECTING。进而会重新进行全量同步流程。


在2.8版本中,Redis增加了psync命令,并且增加了一个复制积压缓冲区的数据结构(默认为1M)。
复制积压缓冲区是一个环形的结构,保存了最近可用的写命令数据。
replicationCron定时任务中每秒发送一个REPLCONF ACK OFFSET命令将自身的偏移量信息发送给master,如果offset的命令在复制积压缓冲区中,那么说明增量数据是可用的。就没必要进行全量同步,直接将复制积压缓冲区中的增量数据发送给slave就可以了。

在redis4.0+版本中又引进了psync2命令来避免一些特殊场景(主从架构、级联架构)下发生主从切换后不必要的全量同步操作。
将一组replid和offset给增加成为两组。主要用来记录上一次复制中主实例的runid值。然后在slaveof时判断是否有必要进行全量同步操作。

1
2
3
4
5
6
replid1:
主节点:自身的replid和offset
从节点:主节点的replid和offset

replid2:
上一次主实例的replid和offset