redis的主从复制原理
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的主从复制原理的更多相关文章
- 5.如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么?
作者:中华石杉 面试题 如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么? 面试官心理分析 其实问这个问题,主要是考考你,redis ...
- Redis 主从复制原理及雪崩 穿透问题
定义: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMw ...
- Redis主从复制原理总结
和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redi ...
- 【*】深入理解redis主从复制原理
1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveof 命令中主节点的信息,并没有立即发起复制. 从节点内部的定时任务发现有主节点的信息,开始使用 socket 连接主节点 ...
- 深入Redis 主从复制原理
原文:深入Redis 主从复制原理 1.复制过程 2.数据间的同步 3.全量复制 4.部分复制 5.心跳 6.异步复制 1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveo ...
- redis之(十四)redis的主从复制的原理
一:redis主从复制的原理,步骤. 第一步:复制初始化 --->从redis启动后,会根据配置,向主redis发送SYNC命令.2.8版本以后,发送PSYNC命令. --->主red ...
- Redis面试篇 -- Redis主从复制原理
Redis一般是用来支撑读高并发的,为了分担读压力,Redis支持主从复制.架构是主从架构,一主多从, 主负责写,并且将数据复制到其它的 slave 节点,从节点负责读. 所有的读请求全部走从 ...
- Redis主从复制以及主从复制原理
Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API.从 2010年 3 月 15 日起,Redis 的开 ...
- 彻底搞懂Redis主从复制原理及实战
欢迎关注公众号:「码农富哥」,致力于分享后端技术 (高并发架构,分布式集群系统,消息队列中间件,网络,微服务,Linux, TCP/IP, HTTP, MySQL, Redis), Python 等 ...
随机推荐
- Pytorch报错:cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorMath.cu:26
Pytorch报错:cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/TH ...
- kbmMW Scheduler.InAMoment用法
kbmMW Scheduler提供了一个方法InAMoment,由于没有找到调用的例子,只好查看代码,原来这个方法与RunNow差不多,是立即执行一个方法,并且在主线程中. Scheduler.InA ...
- 简单服务器通信 模型socketserver
硬件服务器:主机 集群 厂商 :IBM HP 联想 浪潮 软件服务器 :编写的服务端应用程序,在硬件服务器上运行,一般依托于操作系统,给用户提供一套完整的服务 httpserver --> ...
- db2数据库的备份与还原
前言: 数据备份的重要性: 提高系统的高可用性和灾难可恢复性:(在数据库系统崩溃的时候,没有数据库备份怎么办!) 使用数据库备份还原数据库是数据库系统崩溃时提供数据恢复最小代价的最优方案:(总不能让客 ...
- Centos7虚拟机根分区扩展
线上的kvm虚拟机,原来只规划了8G,后来发现硬盘动不动就被日志塞满了,需要进行扩容. 扩容步骤如下: 1.先把kvm虚拟机关机 2.在宿主机上进行kvm虚拟机的磁盘扩容 qemu-img resiz ...
- CentOS 6.10 系统安装
本章内容: CentOS 6.10 的安装 一.安装光盘,选择 Install or upgrade an existing system 二.选择 skip 跳过光盘检查 三.选择 Next 四.选 ...
- Django框架orm
一.django目录 二.登录注册 三.三件套 四.orm简介 五.基于orm的用户登录 一.django目录 -settings -urls -views -强调:setting中的'django. ...
- web开发:css总结与应用
一.常用标签的使用 二.边界圆角 三.背景样式 四.精灵图 五.盒模型布局细节 六.盒模型案例 七.w3c主页 一.常用标签的使用 <!DOCTYPE html> <html> ...
- idea的使用问题解决
IDEA集成SVN插件,用的是TortoiseSVN,SVN上明明有别人提交的内容,但是我这里点击Incoming确显示不出来 解决方案:file->Invalidate Cache/Resta ...
- java——多线程—启动线程
继承Thread启动线程 package com.mycom.继承Thread启动线程; /** * * 继承Thread类启动线程的步骤 * 1.定义自定义线程类并继承Thread * 2.重写ru ...