复制

作者: 简书徐小耳 | 来源:发表于2018-12-10 13:44 被阅读6次
redis复制的概述

本文讲的是复制包含了RDB以及AOF

  • 通过配置slaveof选项或者执行SLAVEOF命令 可以一个服务器去复制另外一个服务器。被复制的服务器我们称为主服务器(master),而对主服务器进行复制的服务器我嗯称为从服务器(slave)
  • 比如我们在从服务器上面执行SLAVEOF 主服务器IP+port。
  • 比如我们在从服务器上面配置slaveof 主服务器ip+port
旧版本复制功能的实现

复制分为同步(sync)和命令传播(command propagate)

  • sync 主要是将从服务器的数据库状态更新至主服务器
  • command propagate 主要是将主服务器数据被命令修改后,将该命令传播到从服务器
sync

服务器执行SLAVEOF命令时,首先需要执行同步操作,具体的操作命令如下:

  • 1.从服务器想主服务器发送SYNC命令
  • 2.收到SYNC命令的主服务器执行BGSAVE,在后台生成一个RDB文件,并使用一个缓冲区去记录从现在开始执行的所有写命令
  • 3.当主服务器执行完毕BGSAVE命令后,会将生成的RBD文件发送给从服务器,从服务器接受并载入RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态
  • 4.主服务器将再此期间的所有写命令发送给从服务器,从服务器执行这些命令


    image.png
command propagate
  • 当我们完成了sync之后还需要传播命令 这样主从才会一致。
旧版本的缺陷
  • 对于初次复制还是ok的,但是对于断线后的复制则存在效率非常低,每次还需要重新复制整个RDB文件
新版本复制功能的实现
  • 使用PSYNC替代SYNC,其中PSYNC包含完整同步和部分重同步
  • 完整同步用于初次复制其和SYNC过程一直
  • 部分重同步则适用于断线后重复制情况:即只需要执行断线后主服务器执行的写命令即可


    image.png
部分重同步的实现

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

  • 主服务器每次成功向从服务器传播N个字节的时候,就将自己的复制偏移量的值加上N
  • 从服务器每次成功接收到主服务器传播的N字节数据,就将自己的复制偏移量增加N

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

  • 缓冲区是一个固定长度,先进先出的队列,默认大小为 1MB
  • 因为是固定长度 这就意味着当长度满的时候,后入的元素会剔除签名的元素
  • 主服务器在命令传播期间,命令不仅发送给从服务器,还会写入的命令复制到缓冲区


    image.png
  • 复制缓冲区的构造如下:


    image.png
  • 当断线重连后执行PSYNC命令时候,有两种情况考虑:1.如果从的offset偏移量之后的数据还在缓冲区,则执行重同步。2。如果不在则还是需要执行完整同步

服务器的运行ID

  • 如果断线重连后,主服务器检测到运行的从ID与之前的一致,那么就可以重试部分重同步操作。
  • 如果不一致只能完全同步
PSYNC命令的实现

调用PSYNC命令有2种方式

  • 1.如果从服务器以前没有父之过任何主服务器或者之前执行过SLAVEOF no one(也就是不是任何机器的从服务器) 命令,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC?-1命令,主动请求主服务器执行完整同步
  • 2.相反则想主服务器发送PSYNC <runid> <offset>,runid和offset都是从服务器的,主服务器会根据这两个参数来决定是完整同步还是部分同步
    1. 如果主服务器返回FULLRESYNC <runid> <offset> 代表执行完整同步
  • 4.如果主服务器返回CONTINUE 则执行部分同步
  • 5.如果返回- ERR 则代表主服务器redis版本低于2.8,不识别该命令,从服务器只能发生SYNC命令


    image.png
复制的实现
  • 1.执行SLAVEOF 命令,在redisServer里面设置masterhost和masterport属性,完整这两个属性设置后即返回OK。然后一步执行BGSAVE
  • 2.建立socket链接
  • 3.发送PING


    image.png
  • 4.身份验证:如果从服务器设置了masterauth则进行身份验证否则不验证。同时还要查看主服务器是否开启了requirepass


    image.png
  • 5.发生端口信息
  • 6.同步
    1. 命令传播
心跳检测
  • 在命令传播阶段,从服务器每秒都会向主服务器发生命令:REPLCONF ACK <replication_offset>
  • replication_offset:是从服务器当前的复制偏移量
  • REPLCONF ACK可以检测主从服务器之间的网络连接状态
  • REPLCONF ACK可以辅助实现了min-slaves选项
  • REPLCONF ACK可以检测命令丢失
检测主从服务器之间的网络连接状态
  • 向主服务器执行INFO replication 命令可以看到,相应的从服务器最后一次向主服务器发送的REPLCONF ACK距离现在过了多少秒


    image.png
辅助实现了min-slaves选项
  • redis的min-salves-to-write和min-salves-max-lag两个选项可以防止服务器在不安全的情况下执行写命令,比如上述两个选项我们设置3和10,则在从服务器少于3个或者三个从服务器的延迟(lag)值都大于或等于10秒的时候,主服务器将拒绝写命令
  • 这样的好处就是我们可以知道我们的命令是否成功的被复制
检测命令丢失
  • 主服务器根据从服务器返回的offset检测从服务器的写命令是否丢失,如果丢失则主服务器从缓冲区拿取到相应命令重新提交给从服务器

相关文章

  • Copy

    copy 复制 浅复制:指针的复制(地址的复制) 深复制:对象内容的复制 Foundion的基本对象复制 基本对象...

  • Redis 复制原理

    目录: 复制过程 数据间的同步 全量复制 部分复制 心跳 异步复制 复制原理 1. 复制过程 复制的过程步骤如下:...

  • iOS常见面试题

    1、浅复制和深复制的区别 浅层复制:只复制指向对象的指针,而不复制引用对象本身。 深层复制:复制引用对象本身。 意...

  • objective深浅拷贝

    浅复制和深复制的区别? 浅复制:只复制指向对象的指针,而不复制引用对象本身。 深复制:复制引用对象本身。 意思就是...

  • Redis——主从复制

    主从复制 : 主从复制实现:slaveof配置文件:slave ip port 复制方式全量复制全量复制全量复制开...

  • Object-C 基础知识

    --------------------| 浅复制和深复制区别 |------------------- 浅复制(...

  • iOS面试题:浅复制和深复制的区别?

    浅层复制:只复制指向对象的指针,而不复制引用对象本身。深层复制:复制引用对象本身。意思就是说我有个 A 对象,复制...

  • 为什么在头条上不容易复制

    在头条写一篇文章,复制了半天才复制一段,再复制又无法复制了,过了好长时间又去复制才能复制下来,以前复制没有这样,今...

  • 深拷贝和浅拷贝

    深复制和浅复制 1、概述 对象拷贝有两种方式:浅复制和深复制。 浅复制:拷贝指针 深复制:拷贝整个对象 2、深浅复...

  • OC属性常用关键字

    含义: copy 复制内容(深复制),如果调用copy的是数组,则为指针复制(浅复制),仅仅复制子元素的指针。 @...

网友评论

      本文标题:复制

      本文链接:https://www.haomeiwen.com/subject/yzerhqtx.html