Redis 的主从同步(复制)
Redis 的主从同步(复制)
Redis 的主从同步(复制)
什么是主从同步(复制)
假设有两个 redis 实例 ⇒ A 和 B
B 实例的内容与 A 实例的内容保持同步
那么称 A 实例是主数据库,B 实例是从数据库
这个过程称为主从同步
为什么要使用主从同步(复制)
- 防止发生单点故障
- 扩展内存
如何开启/关闭主从同步
开启同步
- 配置文件中加入
slaveof 主数据库地址 主数据库端口
- 在命令行中执行上述命令
redis> slaveof 主数据库地址 主数据库端口
- 在开启从服务器时执行命令
$ reids-server --port 6380 --slaveof 主数据库地址 主数据库端口
关闭同步,并成为主数据库
redis> slaveof no one
原理(实现)
复制分为连接建立,数据同步(sync)和命令传播(command propagate)三个阶段
连接建立这里不说,与复制原理无关
下面主要讲数据同步与命令传播两个阶段
redis 从 2.8 版本之后优化了复制功能,咱们先从旧版本的复制说起:
旧版复制过程
| 步骤 | 主服务器 | 从服务器 |
|---|---|---|
| 同步流程 | ||
| 1 | 向主服务器发送 SYNC 命令 | |
| 2 | 收到 SYNC 命令,执行 BGSAVE 生成 RDB 文件 | |
| 3 | 使用缓冲区记录从现在的写命令 | |
| 4 | 将生成的 RDB 文件发送给从服务器 | |
| 5 | 将缓冲区内的写命令发给从服务器 | 接收并载入 RDB 文件 |
| 6 | 接收并执行主服务器发送来的写命令 | |
| 命令传播流程 | ||
| 1 | 发送客户端发过来的写命令 | |
| 2 | 执行主服务器发送过来的写命令 | |
| 断线重连 | 与同步流程一致 | 与同步流程一致 |
经过上述步骤之后主从服务器的状态可以始终保持一致。
细心的读者已经发现了旧版复制的一些问题:
断线重连需要重新走一次同步的流程,而同步流程中的主服务器生成 RDB 文件和从服务器执行 RDB 文件都是特别密集的 IO 操作,这会让断线重连的成本很高
于是从 2.8 版本之后,redis 使用了新的技术来防止重新执行同步流程
新版复制过程
| 步骤 | 主服务器 | 从服务器 |
|---|---|---|
| 完整同步流程 | ||
| 1 | 向主服务器发送 PSYNC 命令 | |
| 2 | 收到 PSYNC 命令,执行 BGSAVE 生成 RDB 文件 | |
| 3 | 使用缓冲区记录从现在的写命令 | |
| 4 | 接收并执行主服务器发送来的写命令 | |
| 5 | 将缓冲区内的写命令发给从服务器 | 接收并载入 RDB 文件 |
| 6 | 将生成的 RDB 文件发送给从服务器 | |
| 命令传播流程 | ||
| 1 | 发送客户端发过来的写命令 | |
| 2 | 执行主服务器发送过来的写命令 | |
| 断线重连过程 | ||
| 1 | 发送 PSYNC 命令 | |
| 2 | 向从服务器发送断线过程中的写命令 | |
| 3 | 执行写命令 |
新版复制经过上述步骤,也可以实现主从数据库状态的一致。
在断线重连过程中,只需要重新执行断线过程中未同步的命令即可,这样就比旧版的复制节省了很多 IO 操作
那么这个断线重连的是怎么实现的呢?
部分重同步(断线重连)的实现
redis 的部分重同步借助了4个变量:
- 服务器的运行 ID (run ID)
- 当实例重启时,会生成40个随机的十六进制字符
- 主服务器的复制积压缓冲区(replication backlog)
- 主服务器每将一个命令传送给从数据库,都会将命令放到一个积压队列(固定长度的循环队列)中
- 主服务器的复制偏移量(replication offset)
- 主服务器将命令放到积压队列中时,会记录下当前命令的偏移量,并发送给从服务器
- 从服务器的复制偏移量
- 从服务器接收到主服务器发送过来的命令与偏移量
也许将这4个变量列出来之后,有读者就可以直接想象出来是怎么实现的了,对,没错,就是这么实现的
过程:
部分重同步流程
| 步骤 | 主服务器 | 从服务器 |
|---|---|---|
| 1 | 发送命令 PSYNC 主数据库的运行ID 断开前最新的命令偏移量 | |
| 判断 1. 运行ID是否能够对应 2. 断开前最新的命令偏移量是否在队列中 满足上述条件可以执行部分重同步,否则执行完全同步 | ||
| 2 | 发送给从数据库偏移量之后的命令 | |
| 3 | 执行命令 |
总结
redis 在很多细节上优化了性能,主从同步(复制)的优化只是其中的一方面。
Redis 的主从同步(复制)的更多相关文章
- Redis的主从同步复制
先来看一下Redis的主从同步复制的原理: 在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台 ...
- 烂泥:mysql5.5主从同步复制配置
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在上篇文章<烂泥:学习mysql数据库主从同步复制原理>中,我们介绍了有关mysql主从复制的基本原理.在这篇文章中,我们来实际测试下mys ...
- percona-xtrabackup工具实现mysql5.6.34的主从同步复制
percona-xtrabackup工具实现mysql5.6.34的主从同步复制 下载并安装percona-xtrabackup工具 # wget https://www.percona.com/do ...
- MySQL数据库的主从同步复制配置
一.主从同步机制原理 MYSQL主从同步是在MySQL主从复制(Master-Slave Replication)基础上实现的,通过设置在Master MySQL上的binlog(使其处于打开状态), ...
- mysql5.5主从同步复制配置
在上篇文章<烂泥:学习mysql数据库主从同步复制原理>中,我们介绍了有关mysql主从复制的基本原理.在这篇文章中,我们来实际测试下mysql5.5的主从同步复制功能. 注意mysql5 ...
- redis之主从同步
很多企业都没有使用到 Redis 的集群,但是至少都做了主从.有了主从,当 master 挂掉的时候,运维让从库过来接管,服务就可以继续,否则 master 需要经过数据恢复和重启的过程,这就可能会拖 ...
- redis 安装 主从同步 哨兵模式
一.redis 的安装1.先将安装包放到linux的一个文件夹下面 2.解压压缩包如图所示 3.解压后进入解压文件 4.安装: make 出现it.s a good idea to run 'make ...
- redis的主从同步
一.redis的主从操作流程 1. 准备三个redis配置文件 #进入redis的配置文件夹,准备好这几个文件,6379不用管,默认的,和这次操作无关 [root@qishi ~]# cd /etc/ ...
- Redis的主从同步手动执行故障切换
1.准备三个redis配置文件,通过端口的区分,启动三个redis数据库实例,然后配置主从复制. # a6371.conf port 6371 daemonize yes pidfile /data/ ...
随机推荐
- 基于 Javassist 和 Javaagent 实现动态切面
一.背景介绍 1.需求说明 需求是在程序运行期间,向某个类的某个方法前.后加入某段业务代码,或者直接替换整个方法的业务逻辑,即业务方法客制化.注意是运行期间动态更改,做到无侵入,而不是事先在代码中写死 ...
- Worker Service in ASP .NET Core
介绍 提到 ASP.NET Core,我们多半会想到 ASP.NET MVC.ASP.NET Web API.Razor page 及 Blazor.随着 .NET Core 3.0 的推出,今天会介 ...
- Java版SockeDemo案例,有很详细的注释
一般是用一个线程池来处理接受到的请求 直接上代码(一) ServerThread层 import java.io.BufferedReader; import java.io.InputStreamR ...
- cesium中json,geojson,stk,影像切片等数据的加载
cesium中json.topojson.geojson.stk,影像切片等数据的加载 一.geojson.topojson,json数据的加载 不管是哪种json,都可以通过GeoJsonDataS ...
- 【Offer】[44] 【数字序列中某一位的数字】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 数字以0123456789101112131415..的格式序列化到一个字符序列中.在这个序列中,第5位(从0开始计数)是5,第13位是 ...
- 联邦学习开源框架FATE助力腾讯神盾沙箱,携手打造数据安全合作生态
近日,微众银行联邦学习FATE开源社区迎来了两位新贡献者——来自腾讯的刘洋及秦姝琦,作为云计算安全领域的专家,两位为FATE构造了新的功能点,并在Github上提交修复了相关漏洞.(Github项目地 ...
- nginx部署成功却没有办法访问
1.首要想到的问题是防火墙没关 注意:因为centos7.0默认不是使用iptables方式管理,而是firewalld方式.CentOS6.0防火墙用iptables管理. 2.解决: ①首先查看防 ...
- golang时间转换
1.datetime转换成时间字符串 package main import ( "fmt" "reflect" "time" ) func ...
- shell脚本中添加用户并设置密码
有时候在初始化shell脚本中希望能顺便创建用户并指定密码,使用useradd命令可以达到该效果: useradd -m -p encryptedPassword username 参数说明: -m ...
- response中文乱码问题
1.要确定I代码的编码格式为UTF-8 2.乱码原因:浏览器和服务器的编码格式不同: 服务器的默认编码为:ISO-8859-1,如果浏览器的编码不是ISO-8859-1,就会出现乱码: public ...