Redis(五):Redis的主从同步

1、同步

2、命令传播

  2.1 旧版复制功能的缺陷

  2.2 新版复制功能的实现


    redis的复制功能分为同步和命令传播两个操作,同步操作用于将从服务器的数据库状态更新至主服务器所处的数据库状态。命令传播操作则用于主服务器的数据库状态被修改时,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。redis的复制功能主要通过执行SLAVEEOF命令来实现。

1、同步

    从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC的执行步骤:

  • 从服务器向主服务器发送SYNC命令;
  • 收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令;
  • BGSAVE命令执行完毕时,主服务器将RDB文件发送给从服务器,从服务器接收这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态;
  • 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态;

2、命令传播

2.1 旧版复制功能的缺陷

    Redis2.8以前从服务器对主服务器的复制可以分为两种情况:

  • 初次复制:从服务器以前从没有复制过任何服务器,这是第一次复制
  • 断线后复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重新连接上了主服务器,并继续复制主服务器。

    对于初次复制来说,旧版复制功能可以很好的完成任务,但是对于断线后重复制来说,旧版复制功能的效率很低。因为旧版的断线后重复制从服务器会向主服务器发送SYNC命令,而主服务器会将数据库中所有的键值对生成RDB文件,发送给从服务器。这种让主重服务器重新执行一次SYNC命令,这种做法是非常低效的。

2.2 新版复制功能的实现

    为了解决旧版功能断线时复制的低效问题,Redis从2.8版本开始,使用PSYNC命令来代替SYNC命令来执行复制时同步操作。PSYNC的完整重同步用于处理初次复制情况,完整重同步和SYNC命令的初次复制情况相同。而部分重同步则用于处理断线后的复制情况,断线后重连接时,主服务器将从服务器连接断开期间执行的写命令发送给从服务器,从服务器只接收这些命令,就可以将数据库更新至主服务器当前所处的状态。PSYNC的部分重同步功能由以下三个部分构成:

(1)复制偏移量:

    主从复制的双方,会分别维护一个复制偏移量,主服务器每复制N个字节时,就将自己的复制偏移量加上N,从服务器每接收到N个字节时,就将自己的复制偏移量加上N。通过对比主从服务器的复制偏移量,程序可以很容易的直到主从服务器是否处于一致状态:

  • 如果主从服务器处于一致状态,那么主从服务器的偏移量总是相同的;
  • 相反,如果主从服务器的偏移量不同,那么说明主从服务器并未处于一致状态

(2)复制积压缓冲区:

    复制积压缓冲区是主服务器维护的一个固定长度的先进先出的队列,默认大小为1M,也可以根据配置文件中的repl-backlog-size来设置。当主服务器进行命令传播时,它不仅会将写命令发送给所有重服务器,还会将写命令入队到复制积压缓冲区,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。当从服务器重新连接上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作:

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

(3)服务器运行ID:

    除了复制偏移量和复制积压缓冲区外,实现部分重同步还要用到服务器的运行ID,每个Redis服务器,不管主服务器还是重服务器,都会有自己的运行ID,当进行初次复制时,主服务器会将自己的运行ID发送给从服务器,从服务器会将这个ID保存起来。当从服务器断线重连接主服务器时,从服务器会向当前连接的主服务器发送之前保存的运行ID:

  • 主服务器收到这个ID后,如果和自己的ID相同,则尝试进行部分重同步;
  • 如果收到的ID和自己的运行ID不同,则主服务器进行完整重同步操作。

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/113794121
今日推荐