Redis的主从复制使用SLAVEOF命令
作用:使一台Redis服务器成为另一台Redis服务器的复制,成为另一台服务器(主服务器)的从服务器。从服务器数据库中的所有数据与主服务器相同,且会复制之后的主服务器上执行的写命令。
一台服务器成为主服务器的从服务器的复制过程,具体分为同步和命令传播两步。
命令传播
- 主服务器执行的所有写命令也会发给从服务器,让从服务器执行
同步:SYNC命令
Redis 2.8版本之前,均使用SYNC命令实现主从复制的同步操作。
具体步骤:
- 从服务器向主服务器发送SYNC命令
- 主服务器收到,开始执行BGSYNC命令,在此命令下,主服务器开始生成RDB文件,并且使用缓冲区记录从现在开始的所有写命令
- 主服务器的BGSYNC命令执行完毕,RDB文件生成完毕,发送给从服务器
- 主服务器将缓冲区内的所有命令发送给从服务器,从服务器执行命令
同步:PSYNC命令
Redis 2.8版本之后,使用PSYNC命令代替SYNC命令,PSYNC有完整重同步和部分重同步两种模式,完整重同步模式类似SYNC命令,用于初次同步。部分重同步模式用于断线之后重新同步的过程。
部分重同步的实现借助三个机制:复制积压缓冲区、复制偏移量和服务器运行ID。
步骤:
- 主服务器维护一个固定长度(默认为1MB)的FIFO队列,在命令传播时不仅将命令发给从服务器,也同时压入复制积压缓冲区。
- 主从服务器各自维护一个复制偏移量,主服务器记录发送给从服务器的数据字节数,从服务器记录从主服务器接收到的数据字节数。
- 每个Redis服务在启动时会随机生成一个长度为40的随机十六进制字符串,作为服务器运行ID,作为本次服务运行的唯一标识
- 从服务器向主服务器发送的PSYNC命令会带有断线之前的主服务器的服务器运行ID,主服务器收到从服务器发来的PSYNC命令时,首先检查命令中的服务器运行ID与自身是否一致,若不一致则执行完整重同步。
- 检查PSYNC命令中的复制偏移量,如果还存在复制积压缓冲区,则执行部分重同步,否则执行完整重同步。
- 向从服务器发送复制积压缓冲区中,复制偏移量之后的所有数据
一次完整的主从复制流程:
- 从服务器作为客户端,向主服务器发送SLAVEOF命令,在命令中指定主服务器的IP与端口
- 从服务器与主服务器建立套接字连接。连接建立之后,从服务器成为了主服务器的客户端,因为之后的步骤从服务器会向主服务器发送命令,接收命令回复
- 从服务器向主服务器发送PING命令,检查网络状况、套接字连接是否正常,检查主服务器状态,以及主服务器目前是否可以执行主从复制
- 从服务器收到主服务器的PONG回复,根据主服务器的配置决定是否需要身份验证。需要的话,从服务器向主服务器发送AUTH命令,携带主服务器设置的masterauth密码
- 密码验证通过后,从服务器向主服务器发送监听端口号,用于后续接收数据
- 执行同步操作,即SYNC或PSYNC
- 同步操作完成后,进入命令传播阶段,在此阶段,从服务器会以默认每秒一次的频率向主服务器发送心跳,即命令REPLCONF ACK,携带从服务器当前的复制偏移量
- 通过配置,主服务器可以检查目前存活的从服务器,在从服务器数量小于某个值时,认为此事不安全,拒绝写入命令
- 主服务器在接收到的心跳复制偏移量小于自身的复制偏移量时,会判断这台从服务器发生了命令丢失,主动向从服务器发送复制积压缓冲区中对应的内容