Redis的主从复制主要经历以下的几个阶段:
- 2.8版本以下—-sync
- 2.8-4.0版本—-psync
- 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
6replid1:
主节点:自身的replid和offset
从节点:主节点的replid和offset
replid2:
上一次主实例的replid和offset