Redis主从复制可以根据是否是全量分为全量同步和增量同步。以下对其相应的同步过程及原理做下简要说明。
增量同步
Redis增量同步主要指Slave完成初始化后开始正常工作时,Master发生的写操作同步到Slave的过程。通常情况下,Master每执行一个写命令就会向Slave发送相同的写命令,然后Slave接收并执行。
全量同步
Redis的全量同步过程主要分三个阶段:
- 同步快照阶段:Master创建并发送快照给Slave,Slave载入并解析快照。Master同时将此阶段所产生的新的写命令存储到缓冲区。
- 同步写缓冲阶段:Master向Slave同步存储在缓冲区的写操作命令。
- 同步增量阶段:Master向Slave同步写操作命令。
具体的全量同步步骤如下:
步骤 | 主服务器 | 从服务器 |
---|---|---|
1 | (等待命令进入) | 连接(重连)Master,发送SYNC命令 |
2 | 执行BGSAVE,并使用缓冲区记录此后的所有写命令 | 根据配置的设定,选择继续使用现有数据处理客户端请求,或者直接向客户端报错。 |
3 | BGSAVE执行完毕,向Slave发送快照文件,同时继续缓冲此期间的写命令。 | 丢弃所有旧数据,开始载入快照文件。 |
4 | 快照文件发送完毕、开始向Slave发送存储在缓冲区的写命令。 | 完成对快照文件的解释操作;开始正常接收命令请求。 |
5 | 缓冲区所存储的写命令发送完毕;此后每执行一个写命令,就向Slave发送相同的写命令。 | 执行Master发来的所有的存储在缓冲区里的写命令;此后,接收并执行Master传来的每个写命令。 |
对应的流程图如下:
值得注意的是,当多个Slave尝试连接同一个Master进行全量同步的时候,Redis为尽可能地减少复制所需的工作,设定了两种处理情形:
当有新的Slave连接Master时 | Master的处理策略 |
---|---|
步骤3尚未执行 | 所有Slave都会接收到相同的快照文件 |
步骤3正在执行或已执行 | 待当前的同步流程执行完毕后,对新的Slave重新执行一遍同步流程。 |
由于Redis在复制进行期间,还会尽可能地处理接收的命令请求。为保障Master有足够的内存来创建子进程和创建用于存储写操作命令的缓冲区等操作,同时又不影响Redis处理命令请求的效率,在实际的操作过程中,最好使得主服务器预留30%~45%的内存用于执行上述操作。
主从链
Redis的Master和Slave并没有特别不同的地方,Slave也可以拥有自己的Slave,并由此形成主从链。
Slave对Slave进行复制在操作上和Slave对Master进行复制的唯一区别在于,如果Slave-X拥有Slave-X1,那么当Slave-X在执行步骤4时(即:完成对快照文件的解释操作;开始正常接收命令请求)时,它将断开与Slave-X1的连接,导致Slave-X1需要重新连接并重新同步。
相关参考
- 《Redis In Action》