Redis复制的原理


Redis复制的原理

一次完整同步的过程

  1. 同步.同步操作使得从服务器的数据库状态与当前主服务器的数据库状态一致
  2. 传播.主服务器会接着处理客户端的命令,此时需要将这些命令传播给从服务器,才能使得数据重新到达一致状态

完整重同步和部分重同步

完整重同步指的是从服务器完整的进行一次主服务器上所有数据的复制.部分重同步指的是只对从服务器缺少的数据进行获取.

完整重同步的实现

  1. 从服务器发送SYNC命令给主服务器
  2. 主服务器执行BGSAVE命令生成一个RDB文件,并使用一个缓冲区记录从生成RDB文件之后的所有写命令
  3. 主服务器将RDB文件发送给从服务器,从服务器加载RDB文件,更新到主服务器执行BGSAVE时数据库状态
  4. 主服务器将缓冲区中的写命令发送给从服务器,从服务器执行这些写命令,主从数据库达到一致状态

部分重同步的实现

新版Redis复制功能中,使用PSYNC来进行数据的同步,具有两种模式,一种是完整重同步,用于处理初次复制的情况,这种模式和SYNC模式完全一样,另外一种是部分重同步,用于处理断线之后复制的情况

  • 部分重同步由三个部分来实现:
    • 复制偏移量.主服务器和从服务器都维护复制偏移量,主服务器传播数据给从服务器后,会将偏移量加上N,从服务器收到数据后,也会将偏移量的值加上N
    • 复制积压缓冲区.复制积压缓冲区由服务器维护的一个固定的FIFO队列实现.当主服务器传播命令时,除了将命令发送给从服务器,也会将命令写入队列中,复制积压缓冲区中的每个字节都会有一个偏移量值.当从服务器断线重新连接到主服务器时,从服务器将会把当前自己的偏移量值发给主服务器,如果偏移量存在于复制积压缓冲区中且从服务器复制的主服务器为本主服务器,那么将执行部分重同步,否则将执行完整重同步.
    • 服务器运行ID.当从服务器首次复制一个主服务器时,主服务器会向从服务器发送自己的服务器标识,从服务器会保存这个标识.当从服务器断线重新去复制主服务器时,会将这个服务器标识发送给主服务器,如果这个标识不是主服务器的标识,那么说明复制的主服务器改变了,只能执行完整重同步操作,否则主服务器根据偏移量是否在复制积压缓冲区来决定执行完整重同步操作或者是部分重同步操作

心跳检测

在命令传播阶段,从服务器会以每秒一次的频率,向主服务器发出REPLCONF ACK OFFSET命令,作用如下:

  • 主服务器会记录从服务器上次发送ACK的时间,用lag来表示,用来判断主从服务器之间的连接是否出了问题
  • 辅助实现mini-slave配置,如果某个从服务器的lag太大,那么主服务器可以拒绝客户端传输的写命令
  • 从服务器在ACK中发送偏移量给主服务器,当主服务器发现从服务器的偏移量不等于自己的偏移量,这个时候可能是发生数据丢失了,那么将会从复制积压缓冲区中获取数据,重新发送给从服务器

参考资料

Redis设计与实现 第15章 复制


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!