码迷,mamicode.com
首页 > 其他好文 > 详细

Redis主从复制

时间:2018-10-26 22:19:25      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:导致   set   nc命令   初始   端口   利用   接受   在服务器   没有   

一. 概念

  在主从复制中,数据库分为两类,一类是主库(master),另一类是同步主库数据的从库(slave)
  主库可以进行读写操作,当写操作导致数据变化时会自动同步到从库。而从库一般是只读的(特定情况也可以写,通过参数slave-read-only指定),并接受来自主库的数据,
  一个主库可拥有多个从库,而一个从库只能有一个主库。

二. 配置方式

2.1 客户端命令

  在从服务器上执行 slave  masterIP masterPort;

2.2 配置文件

  在配置文件中配置  slaveof <masterip> <masterport>;除了IP和端口信息外,还可以配置其他主从信息;

三. 旧版复制功能的实现(Redis2.8以前的版本)

  slave 向 master 发送 slaveof 命令后,slave先进行同步操作,再进行命令传播;

  Redis的复制功能主要分为同步(sync)和命令传播(command propagate)两个操作;

  先通过同步将master和slave的数据库状态达到一致,然后通过命令传播实时的将master的变化同步到slave;

  同步:将 slave 的状态更新为和 master 一样的状态;

  命令传播:master 被修改时将变化实时的同步到 slave;

3.1 同步

  1. slave向master发送sync命令;
  2. master收到sync命令后先执行bgsave命令,后台生成一个RDB文件,同时用一个缓冲区记录从现在开始执行的写命令;
  3. master将生成的RDB文件发送给slave;
  4. 缓冲区的写命令发送给slave;

3.2 命令传播

  同步操作执行完毕后,master将自己执行的写命令发送给slave,slave执行命令,master和slave保持一致;

3.3 旧版复制功能的缺陷

  复制的两种情况:

  初次复制:slave没有复制过任何主服务器,或者复制的主服务器和上次的不同;

  断线后复制:命令传播阶段的master和slave断连,重新连接后重新复制(先进行同步,再进行命令传播),效率较低;

3.4 sync命令非常消耗资源

  • maser执行bgsave,好肥大量的CPU,内存和IO资源;
  • RDB文件传输耗费网络资源;
  • slave载入RDB文件时发生阻塞;

4. 新版复制功能的实现(Redis2.8版本开始)

  为了解决断线后复制的低效问题,Redis2.8版本开始使用PSYNC命令代替SYNC命令;

4.1 PSYNC的两种模式

  • 完整重同步:用于初次复制的情况。和sync命令一样,master创建RDB文件,在缓冲区保存之后的写命令,然后发送给slave;
  • 部分重同步:用于断连后重复制的情况。master和slave断连后重新建立连接,如果条件允许,master可以只将断连期间的写命令发送给slave,这样也可以完成同步,而且效率很高。

4.2 部分重同步的实现

  部分重同步主要由以下三个部分构成:

  • master和slave的复制偏移量;
  • master的复制积压缓冲区;
  • 服务器的运行ID;

  重连后slave将自己的偏移量发送给master,master就知道slave需要同步哪些数据。至于是完整重同步还是部分重同步则根据slave的复制偏移量和积压缓冲区的关系进行选择;

4.2.1 复制偏移量

  master和slave各自维持一个复制偏移量。根据偏移量即可判断master和slave是否一致。

  master每次想slave传播N个字节,就将自己的复制偏移量+N;

  slave每次收到N个字节,就将自己的复制偏移量+N;

4.2.2 复制积压缓冲区

  复制积压缓冲区是由master维护的一个固定长度的先进先出队列,默认在1MB。用于保存一定数量最新的写命令。

  master将命令传播给slave时,还会将命令写入复制积压缓冲区里面;

  重连后master收到的slave的复制偏移量在复制积压缓冲区中,表明需要同步的数据全部可以再复制积压缓冲区中取到,则进行部分重同步;否则进行完全重同步。

  合理的设置复制积压缓冲区的大小可以有效的利用部分重同步模式;

  大小公式:缓冲区大小 = 断连时间秒数 * 每秒的写命令;

4.2.3 服务器运行ID

  每个Redis服务器都有自己的运行ID,它在服务器启动时生成,由40个随机的16进制字符组成。

  初次复制时,master将自己的运行ID发送给slave并保存;

  master和slave断线重连后,slave将保存的master运行ID发送给当前连接的主服务器。

  发送的ID和当前主服务器ID一致则尝试进行部分重同步,否则进行完整重同步;

4.3 PSYNC命令的实现

  • slave没复制过任何master或者执行过 slaveof no one:slave发送PSYNC ? -1命令,请求完整重同步;
  • slave复制过master:slave发送 PSYNC  <runid> <offset>,master自己判断进行何种同步;
  • master 返回 +FULLRESYNC  <runid> <offset> 回复,则进行完整重同步,slave保存这个 runid,并将该 offset 作为自己的初始化 offset
  • master 返回 +CONTINUE 回复,则进行部分重同步,slave等待数据即可;
  • master 返回 - ERR,表示master版本低于2.8;则slave发送 SYNC 命令,进行完整重同步;

5. 复制的实现

 

  



Redis主从复制

标签:导致   set   nc命令   初始   端口   利用   接受   在服务器   没有   

原文地址:https://www.cnblogs.com/virgosnail/p/9858662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!