1. 前言

和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis主从复制可以根据是否是全量分为全量同步和增量同步。

2. 旧版复制功能实现

redis复制功能分为同步和命令传播两种操作:

(1)同步操作负责将从数据库的状态更新为和主数据库状态一致

(2)命令传播操作则用于当主服务器状态修改时,让从服务器状态重新回到一致

2.1 同步

同步操作由sync操作完成:

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

(2)收到sync命令的主服务器执行BGSAVE命令,生成RDB文件,并使用一个缓冲区缓存生成RDB期间所有的写命令

(3)RDB生成完成时,发送RDB给从服务器,从服务器载入RDB,状态和主服务器一致

(4)然后主服务器将缓冲区中的写命令全部传给从服务器,状态一致

2.2 命令传播

同步操作完成后,主从状态一致,但是每当客户端向主服务器执行写命令时,主服务器会修改,和从服务器状态不一致,为了让主从状态重新回到一致,主服务器会发送写命令给从服务器,让从服务器回到和主服务器一致的状态。

2.3 旧版复制功能的不足之处

在redis2.8之前,主从服务器的复制会分为两种:

(1)初次复制:从服务器以前从没复制过其他主服务器,或者从服务器的主服务器换了

(2)断线后复制:处于命令传播阶段的主从服务器,发生了断线,重新连上后,从服务器继续复制主服务器

为什么说效率低呢?因为在旧版复制中,断线重新连接后进行的复制,是通过sync命令实现的,而之前说了sync命令实现是主服务器重新生成RDB文件,发送给从服务器,重新生成RDB是很低效的,而且主服务器生成RDB时是阻塞状态的,所以旧版复制是低效率的。

3. 新版复制功能实现

为了解决旧版复制低效问题,新版复制采用了psync命令来代替sync命令,psync命令具有完全重同步和部分重同步:

(1)完全重同步:和上面的sync一样

(2)部分重同步:专门用于负责处理断线后重连,通过重连后只执行断线期间的写命令而不是全同步来达到高效

3.1 部分重同步实现

部分重同步实现由以下三部分构成:

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

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

(3)服务器运行ID

3.1.1 复制偏移量

主从服务器都会维持一个复制偏移量:

  • 主服务器每次向从服务器发送n个字节的命令,就在自己复制偏移量加n
  • 从服务器每次接收到n个字节数据,就在自己复制偏移量加n

例如,主从服务器当前偏移是100,主向从服务器发送33个字节命令,那么主从此时的复制偏移量都是133,所以判断主从当前状态是否一致,可以通过复制偏移量来判断:复制偏移量如果一样,就代表状态一致,否则不一致。如果断线时,从服务器因为收不到命令,而主服务器一直发送命令,这时的偏移量肯定不一样,所以状态不一致,那么如果让中间漏掉的命令重新传给从服务器呢,这和积压缓冲区有关。

3.1.2 复制积压缓冲区

复制积压缓冲区是一个主服务器维护的固定长度的先进先出队列。每当主服务器进行命令传播时,它不仅将命令传给从服务器,还会将命令写入到缓冲区:

如上图所示,就是一个积压缓冲区的现状,当从服务器重连后,向主服务器发送一个psycn命令,同时会将从服务器当前的复制偏移量(offset)带过去,主服务器会根据从服务器的offset,来决定是全同步还是部分同步:

(1)如果从服务器的offset是10086,那么此时要复制的偏移量应该是从10087开始,在缓冲区存在,将从10087开始往后所有数据都发送给从服务器,所以执行的是部分重同步

(2)相反的,如果不存在,就需要进行全同步了!

如下图:如果进行部分重同步,就向从服务器发送一个CONTINUE回复。

3.1.3 服务器运行ID

除了复制偏移量和复制积压缓冲区之外,实现部分重同步还需要用到服务器运行ID(run ID):

  • 每个Redis服务器,不论主服务器还是从服务,都会有自己的运行ID

当从服务器对主服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来(注意哦,是从服务器保存了主服务器的ID)。

当从服务器断线并重新连上一个主服务器时,从服务器将向当前连接的主服务器发送之前保存的运行ID:

  • 如果从服务器保存的运行ID和当前连接的主服务器的运行ID相同,那么说明从服务器断线之前复制的就是当前连接的这个主服务器,主服务器可以继续尝试执行部分重同步操作;
  • 相反地,如果从服务器保存的运行ID和当前连接的主服务器的运行ID并不相同,那么说明从服务器断线之前复制的主服务器并不是当前连接的这个主服务器,主服务器将对从服务器执行完整重同步操作。

4. 心跳机制

在命令传播阶段时,从服务器每隔一秒都会向主服务器发送命令:REPLCONF ACK <replication_offset>,每发送一次这个命令从服务器都会向主服务器报告一次自己的复制偏移量,如果超过一秒,就代表主从连接出了问题。那此时尽管主服务器发送给从服务器的SET key value丢失了。也无所谓,主服务器马上就知道了,但是要注意,这时的偏移量不一致,并不是断线导致的,而是以为主服务器传给从服务器的命令丢失了,连接情况还是正常的,这种称之为命令丢失。

redis的主从复制原理的更多相关文章

  1. 5.如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么?

    作者:中华石杉 面试题 如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么? 面试官心理分析 其实问这个问题,主要是考考你,redis ...

  2. Redis 主从复制原理及雪崩 穿透问题

    定义: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMw ...

  3. Redis主从复制原理总结

    和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redi ...

  4. 【*】深入理解redis主从复制原理

    1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveof 命令中主节点的信息,并没有立即发起复制. 从节点内部的定时任务发现有主节点的信息,开始使用 socket 连接主节点 ...

  5. 深入Redis 主从复制原理

    原文:深入Redis 主从复制原理 1.复制过程 2.数据间的同步 3.全量复制 4.部分复制 5.心跳 6.异步复制 1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveo ...

  6. redis之(十四)redis的主从复制的原理

    一:redis主从复制的原理,步骤.   第一步:复制初始化 --->从redis启动后,会根据配置,向主redis发送SYNC命令.2.8版本以后,发送PSYNC命令. --->主red ...

  7. Redis面试篇 -- Redis主从复制原理

        Redis一般是用来支撑读高并发的,为了分担读压力,Redis支持主从复制.架构是主从架构,一主多从, 主负责写,并且将数据复制到其它的 slave 节点,从节点负责读. 所有的读请求全部走从 ...

  8. Redis主从复制以及主从复制原理

    Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API.从 2010年 3 月 15 日起,Redis 的开 ...

  9. 彻底搞懂Redis主从复制原理及实战

    欢迎关注公众号:「码农富哥」,致力于分享后端技术 (高并发架构,分布式集群系统,消息队列中间件,网络,微服务,Linux, TCP/IP, HTTP, MySQL, Redis), Python 等 ...

随机推荐

  1. 1.DOS常用命令

    d:+ 回车:盘符切换,进入D:盘 dir(directory):列出当前目录下的文件及文件夹md(make director):创建目录rd(remove director):删除目录(不能删除非空 ...

  2. 【php设计模式】策略模式

    策略模式是针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能. <?php i ...

  3. 安卓开发之Toolbar返回键

    本文前三步演示了为Toolbar添加返回键并实现返回的步骤,第四步给出了设置返回键颜色的方法. 1.在xml布局中引用toolbar: <android.support.design.widge ...

  4. linux 下安装python2.7.13

    1.下载所必要的依赖包 yum -y install python-devel openssl openssl-devel gcc sqlite sqlite-devel mysql-devel li ...

  5. Scala语言面向对象

    apply1. 面向对象的基本概念: 把数据及对数据的操作方法放在一起,作为一个相互依存的整体-----对象,面向对象的三大特征:封装.多态.继承 2. scala类的定义 · class Emplo ...

  6. linux安装vsftpd后无法登陆

    安装完成后在主机上登陆时,不管是输入用户,还是匿名都无法登陆 经过检查,发现是因为/etc/hosts.deny禁止了所有ip访问 将hosts.deny中的all:all删除,或者在/etc/hos ...

  7. 使用Response下载(支持任何格式)

    使用Response下载 下面代码: protected void Button2_Click(object sender, EventArgs e) { Response.ContentType = ...

  8. [Abp vNext微服务实践] - 启动流程

    前几篇分别介绍了abp vNext微服务框架和微服务CI/CD环境搭建,本篇开始介绍vNext微服务框架的开发环境搭建. 环境准备 官方介绍的系统架构图如下: 上图中身份服务和网关服务已经集成在系统中 ...

  9. Python Scrapy爬虫框架之初次使用

    此篇博客为本人对小甲鱼的课程的总结. 关于Scrapy的安装网上都有方法,这里便不再叙述. 使用Scrapy抓取一个网站一共需要四个步骤: 0.创建一个Scrapy项目: 1.定义Item容器: 2. ...

  10. CF901C Bipartite Segments[点双+二分+前缀优化]

    不想翻译了,直接放luogu翻译 说了没有偶环,也就是说全是奇环,再结合二分图性质,那么暴力的话,固定左端点,增大序号,加点直到产生环就不合法了.也就是说,任何一个环,只要他上面的数全都被加了,就不合 ...