EchisanBlog
redis-复制

复制功能的实现

为了解决旧版复制功能在处理断线重复制的低效问题,使用PSYNC命令代替SYNC命令来执行复制时的同步操作

PSYNC命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)两种模式;

  • 其中完整重同步用于处理初次复制情况:完整重同步的执行步骤和SYNC命令的执行步骤基本一样,他们都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步
  • 而部分重同步则用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间的执行的写命令发送给从服务器,从服务器只要接受并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态

部分重同步的实现

部分重同步功能由以下三个部分构成:

  • 主服务器的复制偏移量(replication offset)和从服务器的复制偏移量
  • 主服务器的复制和积压缓冲区(replication backlog)
  • 服务器的允许ID(run ID)

复制积压缓冲区是由主服务器维护的一个固定长度(fixed-size)先进先出(FIFO)队列,默认大小为1MB。

当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入对到复制积压缓冲区里面

当从服务器重新上线连上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作

  • 如果offset偏移量之后的数据仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分重同步操作
  • 相反,如果offset偏移量之后的数据已经不存在于复制积压缓冲区,那么主服务器将对从服务器执行完整重同步操作

根据需要调整复制缓冲区的大小,为了安全起见,可以将复制积压缓冲区的大小设为 2 * second * write_size_per_second,这样可以保证绝大部分断线情况都能用部分重同步来处理