上一篇写了Redis复制功能的简单应用,下面我们看下Redis复制功能的实现过程。下面基本上是理论部分,枯燥乏味,但希望大家能看看,毕竟知识不都是感兴趣的.
耐得住寂寞,经得起诱惑,方能守得住繁华 ~.~
旧版复制功能的实现

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

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

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

从服务器对主服务器的同步操作需要通过向主服务发送sync命令来完成,以下是sync命令的执行步骤:

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

(2)收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录现在开始执行的所有写命令。

(3)当主服务器的BGSAVE命令执行完毕时,主服务器会BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

(4)主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

命令传播:当主服务器执行客户端写命令时,主服务器的数据库就有可能被修改,并导致主从不一致。此时主服务器会将自己执行的写命令发送给从服务器执行,当从服务器执行了相同的写命令后,主从服务器再次回到一致状态。

缺陷

1、初始复制从服务器从来没有复制过任何主服务器或者从服务器当前要复制的主服务器和上次复制的主服务器不同。

2、断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动连接从新连上主服务器,并继续复制。

新版复制功能的实现(PSYNC代替SYNC)

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

(1)完整重同步用于处理初次复制功能,与SYNC功能基本一致;

(2)部分重同步用于处理断线后重复值的情况,解决旧版效率低的问题。

部分重同步的实现:

(1)主服务器与从服务器都会维护一个复制偏移量

(2)复制积压缓冲区是由主服务器维护的一个固定长度先进先出的队列默认(1MB),发生断线从连时,但从服务器重连上主服务器,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器根据这个复制偏移量来决定对从服务器执行何种同步操作:如果offset偏移量之后的数据仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分重同步,反之,执行完整重同步操作。除了复制偏移量和复制积压缓冲之外,实现部分重同步还需要用到服务器运行ID:每个Redis服务器都有自己启动时生成的由40个随机16进制字符组成的运行ID。当服务器对主服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来。当服务器断线重连时,从服务器向主服务器发送保存的运行ID,如果ID一样,则主服务器尝试部分重同步操作,如果不同,则执行完整重同步操作。

PSYNC命令的实现

PSYNC命令的实现方法有两种:

1)如果从服务器以前没有复制过任何主服务器,或者之前执行过SLAVEOF no one命令,那么从服务器在开始新的复制时将向主服务器发送PSYNC? -1 命令,主动请求进行完整重同步。

(2)如果之前复制过某个主服务器,那么从服务在开始一次新的复制时向主服务器发送PSYNC <runid> <offset>。由主服务器来判断该用那种方式同步。

(3)如果主服务器返回+FULLRESYNC回复,则表示主服务器将与从服务器执行完整重同步。

(4)如果主服务器返回+CONTINUE回复,则表示部分重同步,从服务器只需等待接收数据即可。

(5)主服务器返回-ERR回复,则表示主服务器版本低于2.8不识别PSYNC命令从服务器将向主服务器发送SYNC命令完成同步操作。

复制的实现

1、执行SLAVEOF ip port命令,此时从服务器首先将ip与端口保存到服务器状态的masterhost属性与masterport属性里面,并向客户端返回“OK”,表示命令已经被接收。

2、建立套接字连接

从服务器根据ip与端口创建连向主服务器的套接字,如果套接字连接到主服务器,那么从服务器将为这个套接字关联一个 专门用于处理复制工作的文件事件处理器,这个事件处理器负责执行后续复制工作。主服务器在接受从服务器的套接字连接后,将为该套接字创建相应的客户端状态,并将从服务器看作一个连接到主服务器的客户端对待,

3、发送PING命令

作用:

(1)虽然与主服务器建立套接字连接,但双方并未使用该套接字进行任何通信,检查套接字读写是否正常。

(2)检查主服务器是否能够正常处理命令请求。

发送命令后可能遇到的三种情况:

(1)超时,在规定的时间限制内从服务器未收到回复内容,此时从服务器断线重连。

(2)如果主服务器向从服务器回复一个错误,表示主服务器暂时无法处理从服务器的命令请求,从服务器断线重连。

(3)收到正常回复内容,则可以进行下一步操作。

4、身份验证(如果从服务器设置了masterauth选项)

从服务器向主服务器发送一条AUTH命令,此时从服务器可能遇到的情况有:

(1)主服务器没有设置requirepass选项,并且从服务器没有设置master选项,那么从服务器将继续执行从服务发送的命令,复制操作继续。

(2)如果从服务器通过AUTH命令发送的密码与主服务器requirepass设置的密码相同,那么主服务器将继续执行从服务器发送的命令,如果不同则主服务器返回一个invalid password错误。

(3)如果主服务器设置了requirepass选项,但从服务器没有设置masterauth选项,那么主服务器将返回一个NOAUTH选项。另一方面如果主服务器没有设置requirepass选项,但服务器设置了masterauth选项,那么主服务器将返回一个no password is set 错误。

5、发送端口信息,从服务器将执行REPLCONF listening-port port命令,向主服务器发送从服务器的监听端口号,主服务器将端口号保存在对应的客户端状态slave_listening_port属性中。

6、同步

7、命令传播

主服务器将自己执行的写命令发送给从服务器,从服务器只要一直执行主服务器发来的命令即可。

心跳检测

在命令传播阶段,从服务器默认以每秒一次的频率向主服务器发送命令:

REPLCONF ACK <replication_offset>

作用:检测主服务器的网络连接状态;辅助实现min-slaves选项;检测命令丢失。

Redis的min-slaves-to-write和min-slaves-max-lag两个选项防止主服务器在不安全的情况下执行写命令。

当从服务器小于min-slaves-to-write或者min-slaves-to-write个数量的服务器延迟lag值都大于等于min-slaves-max-lag时,主服务器将拒绝执行写命令。

如果因为网络故障,主服务器传播给从服务器的写命令半路丢失,那么当从服务器向主服务器发送REPLCONF ACK命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的偏移量,主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器。


每天学一点,总会有收获。

下一步我们看下Redis的Sentinel(哨兵)

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。

Redis学习笔记(十三) 复制(下)的更多相关文章

  1. redis学习笔记(一)——windows下redis的安装与配置

    前言 很久没有写东西了(.......我的水平就是记个笔记),北漂实习的我,每天晚上回来都不想动,但是做为社会主义接班人的我,还是要时刻给自己充充电,趁着年轻,趁着日渐脱发的脑袋还没有成为" ...

  2. Redis学习笔记之Linux下Redis的安装和部署

    0x00 Redis介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相 ...

  3. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  4. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  5. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  6. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  7. Redis 学习笔记4: Redis 3.2.1 集群搭建

    在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...

  8. redis学习笔记(3)

    redis学习笔记第三部分 --redis持久化介绍,事务,主从复制 三,redis的持久化 RDB(Redis DataBase)AOF(Append Only File) RDB:在指定的时间间隔 ...

  9. redis 学习笔记-cluster集群搭建

    一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http://www.redis.io/download 编译很简单,一个make命令即可,不清楚的同学,可参考我之前的笔记: red ...

  10. Redis学习笔记4-Redis配置具体解释

    在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redi ...

随机推荐

  1. 部署企业LNMP架构搭建bbs

    部署企业LNMP架构 1===============部署Nginx 2===============安装及部署Mysql数据库 3===============安装PHP解析环境 4======== ...

  2. c语言----实战植物大战僵尸

    1. 原理 通过指针先找到阳光的地址,然后修改地址对应的值即修改阳光值. 2. 工具 CheatEngine  --- 查询进程中变量的地址 Dll注入工具  -----  注入 VS2017 3. ...

  3. VS2013 配置全局 VC++目录

    原文链接:https://blog.csdn.net/humanking7/article/details/80391914 也许是我VS2013安装的有问题,每次编译程序都要去 项目属性页-> ...

  4. Vue tools开发工具报错Cannot read property '__VUE_DEVTOOLS_UID__' of undefined

    使用 vue tools 开发工具,不显示调试面板中的组件,点击控制台报错: Cannot read property 'VUE_DEVTOOLS_UID' of undefined 在 main.j ...

  5. VB中使用字典存储类对象

    2019独角兽企业重金招聘Python工程师标准>>> NODE类 Public pNext As NODE Public pPrev As NODE Public data As ...

  6. java的基础知识01

    来自<head first java>书籍的摘录

  7. CF思维联系– Codeforces-990C Bracket Sequences Concatenation Problem(括号匹配+模拟)

    ACM思维题训练集合 A bracket sequence is a string containing only characters "(" and ")" ...

  8. P1468 派对灯 Party Lamps(BIG 模拟)

    题目描述 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码. 这些灯都连接到四个按钮: 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄 ...

  9. MySQL 数据库赋权

    1.进入数据库,查看数据库账户 # 进入数据库 mysql –u root –p ---> 输入密码... # 使用 mysql 库 use mysql; # 展示 mysql 库中所有表 sh ...

  10. D. Carousel(分类+构造)

    \(题目的要求似乎很低:只需要不同类的相邻元素不同色就行了.\) 下面的讨论的话,实际上最后一个点是关键,要想到怎么让最后一个点不开新的颜色就简单了. \(分情况讨论:\) \(\color{Red} ...