Redis学习笔记(十三) 复制(下)
上一篇写了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学习笔记(十三) 复制(下)的更多相关文章
- redis学习笔记(一)——windows下redis的安装与配置
前言 很久没有写东西了(.......我的水平就是记个笔记),北漂实习的我,每天晚上回来都不想动,但是做为社会主义接班人的我,还是要时刻给自己充充电,趁着年轻,趁着日渐脱发的脑袋还没有成为" ...
- Redis学习笔记之Linux下Redis的安装和部署
0x00 Redis介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相 ...
- redis 学习笔记(6)-cluster集群搭建
上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...
- Redis学习笔记4-Redis配置详解
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...
- (转)redis 学习笔记(1)-编译、启动、停止
redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- Redis 学习笔记4: Redis 3.2.1 集群搭建
在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...
- redis学习笔记(3)
redis学习笔记第三部分 --redis持久化介绍,事务,主从复制 三,redis的持久化 RDB(Redis DataBase)AOF(Append Only File) RDB:在指定的时间间隔 ...
- redis 学习笔记-cluster集群搭建
一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http://www.redis.io/download 编译很简单,一个make命令即可,不清楚的同学,可参考我之前的笔记: red ...
- Redis学习笔记4-Redis配置具体解释
在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redi ...
随机推荐
- cocos2dx新建项目
首先你得下载好cococs2dx,还有python2.x版本,还有vs2017 然后cmd在你Cocos2dx的路径下输入 python setup.py 然后你就回车回车回车 然后重新打开cmd 这 ...
- MySQL 入门(1):查询和更新的内部实现
摘要 在MySQL中,简单的CURD是很容易上手的. 但是,理解CURD的背后发生了什么,却是一件特别困难的事情. 在这一篇的内容中,我将简单介绍一下MySQL的架构是什么样的,分别有什么样的功能.然 ...
- @SessionAttributes 和 @SessionAttribute的区别
@SessionAttributes 和 @SessionAttribute的区别 Spring MVC中有两个长得非常像的注解:@SessionAttributes 和 @SessionAttrib ...
- Redis介绍及字符串操作
一.前言 不同程序之间实现通信的方法? A.通过不同程序之间建立socket,实现通信.实际应用适用于使用broker,如RabbitMQ,ZeroMQ. B.通过Json,Pickle,利用文件的写 ...
- Eclipse Mac OS 安装中文简体语言包
打开Eclipse软件,在导航Eclipse下拉菜单中点开 About Eclipse 查看版本 我的是 Eclipse IDE for Enterprise Java Developers. Ver ...
- spring-boot下mybatis的配置
问题描述:spring boot项目想添加mybatis的配置,在src/main/resources目录下新建了mybatis-config.xml文件,在application.propertie ...
- CodeForces - 140A New Year Table (几何题)当时没想出来-----补题
A. New Year Table time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...
- awk调用date命令
创建文件date.awk: $ == { cmd = "\"" while (cmd | getline line) { print line } close(cmd) ...
- C. Fountains
\(整体思路没错,但是我貌似太麻烦了.......\) \(分情况讨论\) \(Ⅰ.coin和diamond各选一个物品,这个简单\) \(Ⅱ.在coin中选两个或者在diamond选两个\) \(开 ...
- Spring官网阅读(十一)ApplicationContext详细介绍(上)
文章目录 ApplicationContext 1.ApplicationContext的继承关系 2.ApplicationContext的功能 Spring中的国际化(MessageSource) ...