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 ...
随机推荐
- SSH 超时设置
在阿里云买了一台乞丐版服务器,搭了一个博客,安装了java,mysql,redis等服务,把以前写的知乎爬虫部署上去,看看爬取效果.程序运行一段时间后,发现cmder上的日志不打了,我原以为爬虫挂了, ...
- Heartbeat+Haproxy实现负载均衡高可用
环境说明: 主机名 角色 IP地址 mylinux1.contoso.com heartbeat+haproxy eth0:192.168.100.121 eth1:172.16.100.121 my ...
- Random Number Generator
rand()函数可以产生[0,RAND_MAX]之间的均匀的伪随机数,它定义在头文件stdlib.h中,函数原型: int rand(void); C标准库的实现是: unsigned ; /*ran ...
- ACM成长之路(干货) 我爱ACM,与君共勉
前几天在网上看到,转过来时刻督促一下自己. ACM队不是为了一场比赛而存在的,为的是队员的整体提高. 大学期间,ACM队队员必须要学好的课程有: l C/C++两种语言 l 高等数学 l 线性代数 l ...
- POJ 1287 Networking 垃圾题目
Networking Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22362 Accepted: 11372 Desc ...
- XCTF练习题-WEB-webshell
XCTF练习题-WEB-webshell 解题步骤: 1.观察题目,打开场景 2.根据题目提示,这道题很有可能是获取webshell,再看描述,一句话,基本确认了,观察一下页面,一句话内容,密码为sh ...
- js 如何保存代码段并执行以及动态加载script
1.模块化开发 通常使用的是 export和import 实现代码的共享和导入 2.特殊情况下需要将代码段作为参数传递 可以使用function 的toString方法将整合函数和里面的代码批量转化为 ...
- C. Cave Painting(最小公倍数的应用)
\(\color{Red}{网上的题解都是投机取巧啊,虽然也没错}\) \(Ⅰ.先说一下投机取巧的方法\) \(自己写几个例子会发现k很小的时候满足条件的n就变得很大\) \(所以我们直接暴力从1判断 ...
- POJ3279(开关后续)
描述: 一个\(n*m的矩阵,每个格子有0和1两种状态.每次可以翻一个格子,并且此格子的上下左右都要被翻.\) \(目标状态应该全为0,求最少翻的次数,输出最小字典序的方案\) 这儿可就麻烦了啊,开关 ...
- 前端【JS】,深入理解原型和原型链
对于原型和原型链,相信有很多伙伴都说的上来一些,但有具体讲不清楚.但面试的时候又经常会碰到面试官的死亡的追问,我们慢慢来梳理这方面的知识! 要理解原型和原型链的关系,我们首先需要了解几个概念:1.什么 ...