0%

Redis主从复制

主从复制,用户可以执行SLAVEOF命令或者设置slaveof选项,让一个服务器(从服务器slave)去复制replicate另外一个服务器(主服务器master)。

Redis复制功能分为同步sync和命令传播command propagate:

  • 同步用于将服务器数据库状态更新到主服务器所处的数据库状态。
  • 命令传播用于主服务器数据库状态被修改后,让从服务器数据库重新回到一致状态。

旧版复制功能实现

同步

  1. 从服务器向主服务器发送SYNC命令
  2. 主服务器收到SYNC命令后执行BGSAVE命令,生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
  3. 主服务器BGSAVE执行完成后,将RDB文件发送给从服务器,从服务器接受并载入RDB文件恢复。
  4. 主服务器将记录在缓冲区的所有写命令发个从服务器,从服务器执行这些命令。

命令传播

同步操作完成之后,主从一致,后面每当主服务器有写命令执行,主服务器会执行命令传播操作,将写命令发送个从服务器。

旧版复制功能缺陷

Redis中复制分为:初次复制和断线后复制。旧版复制功能在断线后复制会重新发送SYNC命令执行一次完整的复制,效率十分低下。

新版复制功能实现

新版使用PSYNC命令代替SYNC来执行复制同步操作。PSYNC具有完整重同步和部分重同步两种功能:

  • 完整重同步,和SYNC基本一样,让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区的写命令进行同步。
  • 部分重同步,用来处理断线后的复制,不会完整的执行一遍复制,而是尽可能的从断开的位置继续复制。

部分重同步的实现

  • 主从服务器分别维护一个复制偏移量
  • 主服务器进行命令传播时,不仅会将命令发送给所有从服务器,还会将命令写入到复制积压缓冲区中,从服务器断线重连后将自己的偏移量通过PSYNC发给主服务器,从而根据这个偏移量和积压缓冲区中偏移量进行对比,决定是执行部分重同步还是完整重同步操作
  • 服务器运行ID,主从服务器都会有自己的运行ID

PSYNC命令的实现

参考

  • 《redis设计与实现》(第二版)
坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub