Redis之主从复制的实现原理

Redis之主从复制的实现原理

必备知识:https://blog.csdn.net/sinat_32366329/article/details/81160282 如果不具备RDB持久化知识,请先看完这篇文章。

旧版复制功能的实现

         Redis的复制功能可以分为同步命令传播两个操作:

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

         命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态不一致时,让主从服务器的数据库重新回到一致状态。

同步

         当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先要执行同步操作,即将从服务器的数据库状态更新至主服务器当前所处的数据库状态。

         同步过程步骤如下:

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

同步图解过程

命令传播

在同步操作完毕后,主从服务器两者的数据库状态达到一致,但是如果客户端发送写命令给主服务器时,将导致主从服务器状态不一致。

为了让主从服务器数据一致,主服务器需要对从服务器执行命令传播操作:主服务器会将自己执行的那条写命令,发送给从服务器执行,当从服务器执行了该写命令后,主从服务器将再次回到一致状态。

旧版复制功能的缺陷2.8以前

         在Redis中,从服务器对主服务器的复制可以分为以下两种情况:

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

图解过程如下

严重缺陷

  1. 主服务器在时间T0到T10086过程中一直处于一致状态。这两个服务器的数据是一样的。
  2. 从服务器断开重连后,只需要主服务器的K10087,K10088,K10089三个命令即可,但是主服务器却返回了一个新的RDB文件,如果RDB文件很大,必将导致严重的内存问题。

新版复制功能的实现2.8开始

         为了解决旧版的问题,Redis2.8以后引入了PSYNC代替SYNC命令执行复制时的同步操作。

         PSYNC命令具有完全同步和部分重同步功能。

         完全同步和旧版的同步是一样的。

         部分重同步主要是用于断线后的重复制情况:当从服务器断开重新连接后,如果条件允许,主服务器将断开期间的写命令发给从服务器,从服务器执行断开期间的写命令完成同步,将数据库更新到和主服务器一致。

部分重同步的实现

  1. 主服务器的复制偏移量和从服务器的复制偏移量。
  2. 主服务器的复制积压缓冲区(队列,默认1MB)。
  3. 服务器的允许ID。

主服务器和从服务器都会维护一个复制偏移量,主要是用户对比复制的执行结果。例如主从服务器的复制偏移量均为1000,当主服务器完成了3个写命令后,主服务器偏移量为1003,这时候将3个命令给从服务器执行,从服务器执行完毕,复制偏移量也为1003。

如果主从服务器的数据是一致的,那么他们的偏移量也是一致的。

复制积压缓冲区,在主服务器将写命令给从服务器后,还会写入到复制积压缓冲区,如果执行到了偏移量为1003的时候,从服务器A断开,主服务器继续执行了7个写入命令,这时候主服务器的偏移量为1100,A服务器连接上,请求复制主服务器,这时候主服务器会分情况处理。

1)主服务器不是A从服务器之前复制的主服务器(根据服务器ID判断),执行完全同步。

2)发现A从服务器之前复制的是自己。根据A从服务器的偏移量去复制积压缓冲区中看1004-1100命令是否依然存在,如果存在将1004-1100偏移量的命令返回给A从服务器执行。如果不存在,只能执行完全同步恢复数据一致了。

关注微信公众号(程序员小兔)不定期分享技术

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读