Redis主从复制
redis主从复制,用户可以执行SLAVEOF命令或者设置slaveof选项,让一个服务器(从服务器slave)去复制replicate另外一个服务器(主服务器master)。
Redis复制功能分为同步sync和命令传播command propagate:
- 同步用于将服务器数据库状态更新到主服务器所处的数据库状态。
- 命令传播用于主服务器数据库状态被修改后,让从服务器数据库重新回到一致状态。
旧版复制功能实现
同步
- 从服务器向主服务器发送SYNC命令
- 主服务器收到SYNC命令后执行BGSAVE命令,生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
- 主服务器BGSAVE执行完成后,将RDB文件发送给从服务器,从服务器接受并载入RDB文件恢复。
- 主服务器将记录在缓冲区的所有写命令发个从服务器,从服务器执行这些命令。
命令传播
同步操作完成之后,主从一致,后面每当主服务器有写命令执行,主服务器会执行命令传播操作,将写命令发送个从服务器。
旧版复制功能缺陷
Redis中复制分为:初次复制和断线后复制。旧版复制功能在断线后复制会重新发送SYNC命令执行一次完整的复制,效率十分低下。
新版复制功能实现
新版使用PSYNC命令代替SYNC来执行复制同步操作。PSYNC具有完整重同步和部分重同步两种功能:
- 完整重同步,和SYNC基本一样,让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区的写命令进行同步。
- 部分重同步,用来处理断线后的复制,不会完整的执行一遍复制,而是尽可能的从断开的位置继续复制。
部分重同步的实现
- 主从服务器分别维护一个复制偏移量
- 主服务器进行命令传播时,不仅会将命令发送给所有从服务器,还会将命令写入到复制积压缓冲区中,从服务器断线重连后将自己的偏移量通过PSYNC发给主服务器,从而根据这个偏移量和积压缓冲区中偏移量进行对比,决定是执行部分重同步还是完整重同步操作
- 服务器运行ID,主从服务器都会有自己的运行ID
PSYNC命令的实现
参考
- 《redis设计与实现》(第二版)