Redis的复制功能分为同步和命令传播两个操作:同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态;命令传播操作则用于在主服务器的数据库状态被修改,导致从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。
完整重同步:
- 从服务器向主服务器发送SYNC命令
- 收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
- 当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE时的数据库状态
- 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态
部分重同步:需要记录1.主服务器的复制偏移量和从服务器的复制偏移量 2.主服务器的复制积压缓冲区 3.服务器的运行ID
复制的实现
- 设置主服务器的地址和端口:客户端向从服务器发送slave of命令
- 建立套接字连接:在slave of 命令执行之后,从服务器将根据命令所设置的IP地址和端口,创建向主服务器的套接字连接
- 发送PING命令
ping命令的两个作用:
- 检查套接字的读写状态是否正常
- 检查主服务器能否正常处理命令请求
从服务器发送PING命令后将遇到三种可能的情况
- 如果主服务器向从服务器返回了一个命令回复,但从服务器不能再规定时间内读取出命令回复的内容,表示主从服务器之间的网络连接状态不佳,不能继续执行复制工作的后续步骤
- 如果主服务器向从服务器返回一个错误,表示主服务器暂时不能处理从服务器的命令请求,不能继续执行复制工作的后续步骤
- 如果从服务器读到PONG回复,表示连接正常,继续执行复制的下个步骤
- 身份验证
- 发送端口信息
- 同步:主服务器需要成为从服务器的客户端
- 如果PSYNC命令执行的是完整重同步操作,那么主服务器需要成为从服务器的客户端,才能将保存在缓冲区里面的写命令发送给从服务器执行
- 如果PSYNC命令执行的是部分重同步操作,那么主服务器需要成为从服务器的客户端,才能向从服务器发送保存在复制积压缓冲区里面的写命令
- 命令传播