Redis(二十一):复制,java在线编译器实现原理

Redis的复制功能分为同步(sync/fsync)和命令传播(command propagate)

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

浏览器打开:qq.cn.hn/FTf 免费领取

两个操作。

  • 同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态(从服务器执行)

  • 命令传播操作则用于在主服务器的数据库状态被修改后(前面已经完成同步操作),导致发生了主从不一致的现象时,让主从服务器的数据库重新回到一致状态。(主服务器执行)

同步

当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先会需要去执行同步操作,将自己的状态更新成与主服务器状态一致。(此时从服务器只能读而不可以写了)

从服务器对主服务器的同步操作,需要通过向主服务器发送SYNC命令来完成,具体的执行步骤如下所示

  1. 从服务器向主服务器发送SYNC命令

  2. 主服务器接收到从服务器发送的SYNC命令,此时会进行一个BGSAVE命令,在后台生成一个RDB文件,并且会使用一个缓冲区记录从现在开始执行的所有写命令

  3. 当主服务器完成BGSAVE命令后,主服务器会将生成的RDB文件发送给从服务器,从服务器会接受并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态(注意此时从服务器里面原有的数据就会消失不见)

  4. 主服务完成BGSAVE命令后,还会将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,再将自己的数据库状态更新至主服务器数据库当前的状态(避免了执行BGSAVE时数据的丢失)

在这里插入图片描述

上图可以看到,从服务器的onlymehave字符串对象不见了

在这里插入图片描述

命令传播

同步操作执行完后,从服务器的状态跟主服务器一致了,但这种一致并不是永远保持的,每当主服务器执行客户端发送的写命令时,主服务器的数据库就可能被修改,但从服务器并没有修改,主从又不一致了。

为了让主从再回到一致状态,主服务器就需要对从服务器执行命令传播操作

命令传播操作即:主服务器将自己新执行的写命令,发送给从服务器,从服务器执行发送过来的命令,这样主从状态又一致了。

旧版复制功能的缺陷

旧版复制功能的复制可以分为下面两种情况

  • 初次复制:从服务器在复制以前没有复制过任何主服务器,或者从服务器要复制新的主服务器

  • 断线后重复制:从服务器已经完成同步,处于命令传播状态,在接受主服务器新执行的命令,但此时从服务器由于网络原因与主服务器断开了连接,需要进行重新连接,连接后要进行重新复制

对于第一种情况,旧版是做的不错的。

关键在于第二种情况,断线后重新复制是很浪费资源的(因为重新连接后无法判断此时主从状态是否一致,所以只能重新同步,完成一致),比如说,你主从服务器已经完成同步,已经有1万个键同步好了,但此时你从服务器宕机了,重启后,又去进行同步,又要去复制1万个键,包括宕机时主服务器插入的新键,但实际上,重连的从服务器只需要复制宕机时主服务器插入的新键即可

总结来说,就是Sync命令会十分耗费资源,因为每次执行Sync,主从服务器要进行下列的步骤

  • 主服务器要执行BGSAVE命令生成RDB文件,耗费主服务器的CPU、内存和磁盘IO资源

  • 主服务器执行完BGSAVE之后,还要发送RDB文件给从服务器,耗费网络资源

  • 从服务器接受主服务器发送的RDB文件,然后进行载入RDB文件,此时耗费CPU去读取,而且载入RDB文件时,是会发生阻塞的,从服务器会停止对外提供读服务。

所以,要在真正有必要的时候,才去执行Sync命令

新版复制功能的实现

新版复制功能其实是为了解决旧版的断线重复制的问题(为了解决主从状态是否一致问题),从2.8版本开始,使用Psync命令代替了Sync命令(即从服务器不再发送Sync命令,取而代之的是Psync命令)

Psync命令具有完整重同步和部分重同步两种模式

  • 完整重同步是用于初次复制,也就是第一次同步的情况,完整重同步的执行步骤和Sync基本是一样的,同样主服务器进行BGSAVE,然后发送RDB,缓冲池记录新的写命令,从服务器接受RDB,进行载入,载入后接受主服务器发送缓冲池新的写命令,然后执行新的写命令,完成整个同步操作

  • 部分重同步则是针对于断线后重复制情况的,当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将从服务器连接断开期间执行的写命令发送给从服务器,而不是重新复制,从服务器接收并去执行这些命令,这也就解决了全部重新复制的问题

部分重同步的过程如下图所示

部分重同步的实现

完整重同步的实现跟Sync差不多,这里就不重复了,下面说一下部分重同步的实现

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

  • 主服务器的复制偏移量和从服务器的复制偏移量

  • 主服务器的复制积压缓冲区

  • 服务器的运行ID

复制偏移量

执行复制的双方,也就是主从服务器,都要分别去维护一个复制偏移量(初始为0)

  • 主服务器每次向从服务器发送数据时,要统计发送了多少字节,然后将自己的复制偏移量加上N

  • 从服务器每次从主服务器接受数据时,也要统计接受了多少字节,然后将自己的复制偏移量加上N

这样就可以通过比对主从的复制偏移量,就可以判断主从状态是否一致了

  • 如果主从状态一致,那么主从服务器两者的偏移量总是相同的

  • 如果两者的偏移量不相同,说明了主从状态并不一致

复制积压缓冲区

通过复制偏移量,我们可以判断主从服务器状态是否一致了,但是真正要去执行完整重同步还是部分重同步,就要由复制积压缓冲区去决定了

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

拓展固定长度队列

固定长度队列与普通队列不太一样,普通队列是可以动态改变自己长度的,而固定长度队列则不可以动态改变,而是固定的,正因为是固定的,所以一旦长度达到最大值,此时如果再往里面添加元素,就会弹出最先进入的元素,然后再添加新的元素。

回到复制积压缓冲区

当主服务器进行命令传播时,不仅仅会将写的命令发送给所有服务器,还会将写命令入队到复制积压缓冲区里面。如下图所示

在这里插入图片描述

在复制积压缓冲区会保存着一部分最近传播的写命令,并且会为队列中每一个字节记录其相应的复制偏移量

举个栗子

加入主服务器这里执行了一个新的写命令

set a 12

那么里面这条写命令在复制积压缓冲区里面大概如下图所示

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值