Redis知识(六)--主从复制

引言

  在了解了Redis的底层结构以及持久化机制后,就可以开始学习Redis主从复制的原理了。
  Redis中,通过SLAVEOF命令或者slaveof选项设置就可以实现一个服务器复制另一服务器。
在这里插入图片描述
  Redis2.8版本以前复制为旧版,2.8开始使用新版复制功能。
  Redis中,从服务器对主服务器的复制可以分两种情况:

  1. 初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同
  2. 断线后复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连重新连上了主服务器,并继续复制主服务器

一、旧版复制

  旧版复制功能分为:同步(sync)、命令传播(command propagate)两个部分:

  1. 同步:用于将从服务器数据库状态更新至主服务器的数据库状态
  2. 命令传播:用于主服务器数据库状态修改导致主从数据库状态不一致时,让主从服务器数据库状态一致

1、同步

  从服务器向主服务器发送SYNC命令即开始进行同步,步骤如下:

  1. 从服务器向主服务器发送SYNC命令
  2. 主服务器收到命令后,执行BGSAVE命令后台生成RBD文件,并使用一个缓冲区记录从现在开始之后的写命令
  3. 主服务器生成完RDB文件后,发送给从服务器;从服务器接收该RDB并更新
  4. 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器更新至主服务器当前所处的数据库状态

  下图展示了SYNC期间主从的通信过程:
在这里插入图片描述

2、命令传播

  在主服务器执行了写命令后,主从服务器数据库状态又变成不一致。为了让主从服务器再次回到一致状态,主服务器会执行命令传播操作:将造成主从服务器不一致的那条写命令,发送给从服务器执行。

3、旧版复制缺陷

  对于初次复制来说,旧版能够很好地完成任务;但对于断线后复制来说,旧版复制功能效率低。因为,断线重连后旧版执行的复制,是执行SYNC命令让主服务器生成RDB文件来进行全量复制。一个断线重连的例子如下图:
在这里插入图片描述
  可以发现,断线重连所造成的的数据库状态不一致,只需要执行中断期间主服务器执行的写命令(图中的T10088~T10090)即可让主从数据库状态回到一致,而实际则通过生成整个RDB来进行同步,这样就导致执行了很多不需要同步的写命令。

二、新版复制

  新版复制命令使用PSYNC命令来代替SYNC执行复制时的同步操作。
  PSYNC命令分为两种模式:完整重同步(full resynchronizaiton)部分重同步(partail resynchronization)

完整重同步:用于初次复制的情况,执行步骤与SYNC命令基本一样,都是让主服务器生成并发送一个RDB文件,以及向从服务器发送保存在缓冲区里面的写命令
部分重同步:用于处理断线重连后复制的情况,断线重连后,如果条件允许,主服务器可以将断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,即可将数据库状态更新到与主服务器一致

  一个新版复制的例子如下:
在这里插入图片描述

1、完整重同步

  完整重同步步骤基本与SYNC命令复制步骤一致。

2、部分重同步

  部分重同步功能由三个部分组成:

  1. 主服务器的复制偏移量和从服务器的复制偏移量
  2. 主服务器的复制积压缓冲区
  3. 服务器的运行ID(run ID)

  复制偏移量:主服务器和从服务器会各自维护一个复制偏移量。主服务器每次向从服务器传播N个字节数据时,就将自己的复制偏移量加N;从服务器接收到N个字节数据后,就将自己的复制偏移量加N。
  复制积压缓冲区:由主服务器维护的一个固定长度的先进先出队列,默认1MB。当命令传播时,不仅会将写命令发送给所有从服务器,还会将该命令写入复制积压缓冲区。

从服务器重连上主服务器时,会通过PSYNC命令将自己的复制偏移量offset发送给主服务器。主服务器根据这个复制偏移量来进行判断:
  1、如果offset之后的数据(即offset+1开始的数据)在复制积压缓冲区中,执行部分重同步操作
  2、如果数据不在复制积压缓冲区中,则执行完整重同步操作

在这里插入图片描述
  服务器运行ID:不论主从服务器,每个服务器都有自己的运行ID,这个ID是在启动的时候自动生成的。实现部分重同步的时候也需要用到服务器运行ID。

当从服务器重连上主服务器时,从服务器会向当前主服务器发送之前保存的主服务器运行ID:当该运行ID与当前连接的主服务器运行ID相同时,说明断线之前复制的就是这个主服务器,主服务器就可以尝试执行部分重同步操作;相反,如果运行ID不同,则主服务器将对从服务器执行完整重同步操作

  新版的复制流程如下图:
在这里插入图片描述

3、命令传播

  与旧版命令传播一致。

三、命令传播中的心跳检测

  命令传播阶段,从服务器默认以每秒一次的频率,向主服务器发送REPLCONF ACK <replication_offset>。replication_offset为当前从服务器的复制偏移量。
  发送REPLCONF ACK主要有三个作用:检测主服务器的网络连接状态、辅助实现min-slaves选项、检测命令丢失
  检测主服务器的网络连接状态: 主从服务器可以通过REPLCONF ACK命令来判断两者之间的连通性。如果主服务器超过一秒没有收到从服务器发来的REPLCONF ACK命令,那么主服务器就知道与该从服务器之间的连接出现了问题。通过向主服务器发送INFO replication,在从服务器列表的lag一栏可以看出距离上一次从服务器发送REPLCONF ACK命令过去了多久(单位:秒)。一般情况下,lag值为0或1。
在这里插入图片描述
  辅助实现min-slaves选项: Redis的min-slaves-to-writemin-slave-max-lag两个选项可以防止主服务器在不安全的情况下执行写命令。
  检测命令丢失: 主服务器发觉从服务器当前的复制偏移量少于自己的复制偏移量,就会根据从服务器发送过来的复制偏移量,在复制积压缓冲区中查找并发送缺少的数据。

总结

1、Redis2.8版本以前为旧版复制,2.8或以上使用新版复制
2、旧版处理断线后重复制效率低,新版部分重同步功能解决了这个问题
3、旧版复制功能使用SYNC命令,分为同步和命令传播两个部分;新版使用PSYNC命令,同步分为完整重同步、部分重同步两种,命令传播与旧版一致
4、部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分实现
5、命令传播用于检测主服务器的网络连接状态、辅助实现min-slaves选项、检测命令丢失

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值