redis复制的设计与实现
一、复制
1.1旧版功能的实现
旧版Redis的复制功能分为 同步(sync)和 命令传播。
- 同步用于将从服务器更新至主服务器的当前状态。
- 命令传播用于 主服务器状态变化时,让主从服务器状态回归一致。
1.1.1同步
当客户端向服务端发送slaveof命令,要求从服务器复制主服务器时,首先从服务器需要进行同步操作。
同步操作需要 从服务器向主服务器发送 SYNC命令 来完成,以下是SYNC命令的执行步骤。
- 从服务器向主服务器发送 SYNC命令
- 收到SYNC命令后,主服务器执行BGSAVE命令,在后台生成RDB命令,并且使用一个 缓冲区 记录从现在开始执行的所以写命令。
- BGSAVE命令执行完毕是,主服务器讲生成的RDB文件发送给从服务器,从服务器接收并载入。
- 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些命令。最终达到同步效果。
注意:在开始执行BGSAVE命令后,记录在缓冲区里的写命令并不会记录在RDB文件中。RDB中记录的是开始BGSAVE命令之前的数据,从以下例子也能看出。

1.1.2命令传播
在同步操作之后,当主服务器执行客户端发送的写命令时,主服务器的数据库可能被修改,导致主从服务器状态不一致。为了使主从的状态回归一致,主服务器需要执行 命令传播 操作。
主 会将自己执行的写命令也即造成状态不一致的命令,发送给从服务器,当从服务器执行相同写命令后,主从状态回归一致。
1.2旧版复制功能的缺陷
1.2.1从服务器对主服务器的复制的两种情况
- 初次复制:从服务器以前没有复制过任何服务器,或者当前要复制的服务器和上次复制的主服务器不同。
- 断线后重复制。
1.2.2 缺陷
对于初次复制的情况,旧版能很好的解决,但是对于断线后重复制,效率就非常低了。
旧版实现断线后重复制的方法是,断线重连后,又执行一遍sync命令。
但是实际上我们仅仅需要同步 断线期间主服务器执行过的写操作。而sync命令是非常耗费资源的操作!
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gVH4HFnv-1682267130057)(C:\Users\chenzhengchang\AppData\Roaming\Typora\typora-user-images\image-20230423112927560.png)]](https://img-blog.csdnimg.cn/19dfec5c079345c7afa11c68a8d2ffea.png)
1.3新版复制功能的实现
从redis 2.8版本开始,使用 PSYNC命令 代替SYNC命令来执行复制时的同步操作。
PSYNC命令具有 完整重同步 和 部分重同步 操作。
完整重同步用于初次复制的情况,和sync命令基本一样。
部分重同步用于断线后重复制的情况。当从服务器断线后重连,如果条件允许,主服务器将 断线期间执行的写命令发送给从服务器,从服务器接收并执行即可。

1.4部分重同步的实现
部分重同步功能由以下三个部分构成:
- 主服务器和从服务器的 复制偏移量(replication offset) ;
- 主服务器的 复制积压缓冲区(replication backlog)
- 服务器的运行ID (run ID)
1.4.1复制偏移量
主从服务器都会维护一个复制偏移量:
- 主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量加上N。
- 从服务器每次接收到主服务器的N个字节后,就将自己的复制偏移量加上N。
对比主从服务器的复制偏移量,相同则状态一致,不同则不一致。
1.4.2复制积压缓冲区
复制积压缓冲区是主服务器维护的一个固定长度的 先进先出 队列,默认大小为1MB。
当主服务器进行命令传播时,会将写命令写入复制积压缓冲区。
主服务器的复制积压缓冲区里面保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的 复制偏移量。
当从服务器重连时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器:
- 如果offset偏移量之后的数据还在复制积压缓冲区,则进行部分重同步。
- 否则,将执行完整重同步。
1.5PSYNC命令的实现细节
PSYNC命令的调用方法有两种

根据情况,主服务器将会有以下三种的某种回复:
- 主服务器返回 +FULLERSYNC ,表示执行完整重同步。runid和offset是主服务器的,从服务器将会以offset作为自己的初始化偏移量。
- 返回 +CONTINUE,表示执行部分重同步。
- -ERR,表示主服务器的版本低于2.8,识别不了PSYNC,将执行SYNC命令。
1.6复制的实现
通过向服务器发送slaveof命令,可以让一个服务器去复制另一个服务器。
slaveof <master_ip> <master_port>
1.6.1步骤1:设置主服务器的地址和端口
从服务器将客户端给定的 主服务器IP及端口绑定到服务器的相关属性中。
slaveof命令是一个异步过程,在完成属性设置后,向发送slaveof命令的客户端返回OK。表示复制指令接收,而实际的复制工作将在O返回后才开始执行。
1.6.2步骤2:建立套接字连接
设置好IP及端口属性后,从服务器将会创建连向主服务器的套接字连接。
如果从服务器创建套接字能成功连接到主服务器,那么从服务器将会为其关联一个专门用于处理复制工作的文件事件处理器,负责后续的复制工作,比如接收RDB文件,接收主服务器传来的写命令等。
主服务器在接收(accept)从服务器的套接字连接后,将为该套接字创建相应的客户端状台3,并将从服务器看作一个连接到主服务器的客户端对待。
1.6.3步骤3,发送PING命令
从服务器成为主服务器的客户端之后,做的第一件事就是向主服务器发送 一个 PING命令。
PING命令的作用:
- 检查套接字读写状态是否正常;
- 检查主服务器能否正常处理请求命令。
发送PING命令后将会遇见以下三种情况的一种:
- 主服务器返回一个命令回复,但是从服务器却不能在规定时间读取出命令回复的内容,表示网络连接状态不佳,从服务器断开并重建 套接字。
- 主服务器回复一个错误,表示主服务器暂时没办法处理从服务器的命令请求。从服务器断开并重建 套接字。
- 从服务器读取到 “PONG”,流程继续正常进行。
1.6.4步骤4:身份验证
从服务器接收到 PONG 后下一步就是决定是否需要身份验证:
以下由流程图来说明这一过程。

1.6.5步骤5:发送端口信息
身份验证后,从服务器向主服务器发送从服务器的监听端口号。主服务器将其记录在从服务器所对应的客户端状态属性中。
1.6.6步骤6:同步
在这一步,从服务器向主服务器发送PYSNC命令,执行同步操作。
值得一提的是,在同步操作执行之前,只有从服务器是主服务器的客户端,同步操作之后,主服务器成为从服务器的客户端。

1.6.7步骤7:命令传播
完成同步操作之后,主服务器就会进入命令传播阶段,只要主服务器一直将执行的写命令发送给从服务器就可以了。
1.7心跳检测
在命令传播阶段,从服务器默认以每秒一次的频率向主服务器发送命令。
REPLCONF ACK <replication_offset>
其中replication_offset是从服务器当前复制偏移量。
该命令注意有三个作用:
- 检测主从服务器的网络连接状态
- 辅助实现min-slaves选项
- 检测命令丢失。
1.7.1检测主从服务器的网络连接状态
通过发送和接收 REPLCONF ACK 命令来检测网络连接是否正常。
如果主服务器超过一秒没有接收到该命令,主服务器就知道它们之间的连接出现问题了。
通过向主服务器发送 INFO replication命令,在从服务器列表的lag一栏可以看到相应从服务器最后一次向主服务器发送REPLCONF ACK 命令距离现在过了多少秒。

1.7.2辅助实现min-slaves配置选项
redis的 min-slaves-to-write 和 min-slaves-max-lag两个选项可以保证防止主服务器在不安全的情况下执行写命令。
前者表示 最小从服务器数量,后者为 最小服务器数量的延迟值需要小于多少秒。
min-slaves-to-write 3
min-slaves-max-lag 10
如果不符合,则主服务器拒绝执行写命令。
1.7.3检测命令丢失
如果复制偏移量对应不上,那么主服务器将会将复制积压缓冲区里的数据发送给从服务器,以维持状态一致。
注:本文为个人学习笔记,文章内容摘自黄健宏《Redis设计与实现》。redis的复制功能是sentinel和集群的基础之一,本文简单概括了redis复制功能的设计与实现,如果想详细了解过程建议看一下Redis设计与实现这本书,强列推荐!
大家有什么疑问可以评论或者私信,一起进步。
多机功能后面会持续更新。
相关文章:
redis复制的设计与实现
一、复制 1.1旧版功能的实现 旧版Redis的复制功能分为 同步(sync)和 命令传播。 同步用于将从服务器更新至主服务器的当前状态。命令传播用于 主服务器状态变化时,让主从服务器状态回归一致。 1.1.1同步 当客户端向服务端发送slaveof命令…...
Docker更换国内镜像源
什么是Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全…...
【网络编程】网络套接字,UDP,TCP套接字编程
前言 小亭子正在努力的学习编程,接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟,如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话,烦请点赞关注支持一波, 感激不尽~~ 特别说明:本文分享的代码运行结果…...
海斯坦普Gestamp EDI 需求分析
海斯坦普Gestamp(以下简称:Gestamp)是一家总部位于西班牙的全球性汽车零部件制造商,目前在全球23个国家拥有超过100家工厂。Gestamp的业务涵盖了车身、底盘和机电系统等多个领域,其产品范围包括钣金、车身结构件、车轮…...
gpt写文章批量写文章-gpt3中文生成教程
怎么用gpt写文章批量写文章 批量写作文章是很多网站、营销人员、编辑等需要的重要任务,GPT可以帮助您快速生成大量自然、通顺的文章。下面是一个简单的步骤介绍,告诉您如何使用GPT批量写作文章。 步骤1:选择好训练模型 首先,选…...
HashMap实现原理
HashMap是基于散列表的Map接口的实现。插入和查询的性能消耗是固定的。可以通过构造器设置容量和负载因子,一调整容易得性能。 散列表:给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字…...
【Java 数据结构】PriorityQueue(堆)的使用及源码分析
🎉🎉🎉点进来你就是我的人了 博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔🦾&am…...
使用 Kubernetes 运行 non-root .NET 容器
翻译自 Richard Lander 的博客 Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。 您可以尝试使用我们的 non-root…...
为什么大量失业集中爆发在2023年?被裁?别怕!失业是跨越职场瓶颈的关键一步!对于牛逼的人,这是白捡N+1!...
被裁究竟是因为自身能力不行,还是因为大环境不行? 一位网友说: 被裁后找不到工作,本质上还是因为原来的能力就配不上薪资。如果确实有技术在身,根本不怕被裁,相当于白送n1! 有人赞同楼主的观点&…...
Word控件Spire.Doc 【脚注】字体(3):将Doc转换为PDF时如何使用卸载的字体
Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…...
keil5使用c++编写stm32控制程序
keil5使用c编写stm32控制程序 一、前言二、配置图解三、std::cout串口重定向四、串口中断服务函数五、结尾废话 一、前言 想着搞个新奇的玩意玩一玩来着,想用c编写代码来控制stm32,结果在keil5中,把踩给我踩闷了,这里简单记录一下…...
中国社科院与美国杜兰大学金融管理硕士项目——在职读研的日子里藏着我们未来无限可能
人生充满期待,梦想连接着未来。每一天都可以看作新的一页,要努力去成为最好的自己。在职读研的光阴里藏着无限的可能,只有不断的努力,不断的强大自己,未来会因为你的不懈坚持而发生改变,纵使眼前看不到希望…...
hardhat 本地连接matemask钱包
Hardhat 安装 https://hardhat.org/hardhat-runner/docs/getting-started#quick-start Running a Local Hardhat Network Hardhat greatly simplifies the process of setting up a local network by having an in-built local blockchain which can be easily run through a…...
【华为OD机试真题】1001 - 在字符串中找出连续最长的数字串含-号(Java C++ Python JS)| 机试题+算法思路+考点+代码解析
文章目录 一、题目🔸题目描述🔸输入输出二、代码参考🔸Java代码🔸 C++代码🔸 Python代码🔸 JS代码作者:KJ.JK🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🍂个人博客首页: KJ.JK 💖系列专栏:华为OD机试(Java C++ Python JS)...
CrackMapExec 域渗透工具使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、CrackMapExec 是什么?二、简单使用1、获取帮助信息2、smb连接执行命令3、使用winrm执行命令(躲避杀软)4、smb 协议常用枚…...
Modbus协议学习
以下内容从参考文章学习提炼 [参考文章](https://www.cnblogs.com/The-explosion/p/11512677.html) ## 基本概念 Modbus用的是主从通讯技术,主设备操作查询从设备。可以通过物理接口,可选用串口(RS232、RS485、RS422),…...
camunda如何处理流程待办任务
在 Camunda 中处理流程任务需要使用 Camunda 提供的 API 或者用户界面进行操作。以下是两种常用的处理流程任务的方式: 1、通过 Camunda 任务列表处理任务:在 Camunda 任务列表中,可以看到当前需要处理的任务,点击任务链接&#…...
git部分文件不想提交解决方案
正确的做法应该是:git rm --cached logs/xx.log,然后更新 .gitignore 忽略掉目标文件,最后 git commit -m "We really dont want Git to track this anymore!" 具体的原因如下: 被采纳的答案虽然能达到(暂…...
2023年全国最新道路运输从业人员精选真题及答案58
百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 69.根据《公路水路行业安全生产风险管理暂行办法》,…...
Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析
Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析 漏洞简介 Zimbra是著名的开源系统,提供了一套开源协同办公套件包括WebMail,日历,通信录,Web文档管理和创作。一体化地提供了邮件收发、文件共享、协同办公、即时聊天等一系列解决…...
Python 实战:数据归一化 4 种核心方法对比 + 代码实现(机器学习必看)
在机器学习、深度学习的数据预处理中,数据归一化是绕不开的关键步骤。不同特征往往量纲不同(比如年龄 18-60、收入 1000-100000),直接训练模型会导致:梯度下降收敛慢、难以最优解距离类算法(KNN、K-Means、…...
SClick技术解析:防休眠工具的工作原理探讨
SClick是一款轻量级的防休眠工具,能够帮助用户解决Windows系统自动休眠带来的诸多不便。 软件体积仅有几十KB,绿色便携,无需安装,即用即走。 它通过模拟鼠标点击的方式,让系统以为用户一直在操作电脑,从而防…...
GHelper终极指南:如何用开源工具彻底掌控华硕笔记本性能
GHelper终极指南:如何用开源工具彻底掌控华硕笔记本性能 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, …...
为什么选择Apache NetBeans?完整对比主流IDE的优势与特色
为什么选择Apache NetBeans?完整对比主流IDE的优势与特色 【免费下载链接】netbeans Apache NetBeans 项目地址: https://gitcode.com/gh_mirrors/ne/netbeans Apache NetBeans是一款由Apache软件基金会开发的开源集成开发环境(IDE)&a…...
linux source命令作用及使用场景
source 是 Linux/Unix 系统中的一个内置 Shell 命令,主要用于在当前 Shell 环境中执行脚本文件(而非启动子 Shell),从而直接影响当前环境(如变量、函数、别名等)。以下是其详细作用及使用场景: …...
新手福音:在快马平台体验vscode codex式辅助,轻松写出第一行代码
最近在学编程,发现很多新手(包括我自己)最头疼的就是面对空白的编辑器不知道从哪下手。传统的学习方式要么是直接看教程照抄代码,要么是硬啃文档记语法,很容易劝退。直到我发现了InsCode(快马)平台的智能辅助功能&…...
Jetson Orin Nano环境搭建避坑实录:从JetPack到PyQt5,我踩过的那些‘坑’都帮你填平了
Jetson Orin Nano环境搭建避坑实录:从JetPack到PyQt5的实战指南 第一次拿到Jetson Orin Nano这块开发板时,我天真地以为按照官方文档就能轻松搞定所有环境配置。结果从JetPack安装到PyQt5编译,几乎每一步都遇到了意想不到的问题。这篇文章不会…...
三相三电平维也纳Vienna整流器DPWM调制仿真之旅
三相三电平维也纳Vienna整流器 DPWM调制仿真 Matlab2020a 双PI控制 锁相环控制 电容电压平衡控制 最大相钳位 过零畸变 零序分量注入实现最大相钳位消除过零畸变 基于载波调制实现 谐波畸变率对比分析 电压利用率对比分析 交流侧电压有效值 220V/50Hz 额定输出功率10kw 直…...
臭氧污染成因难辨?EKMA曲线+OZIPR模型实战,手把手教你锁定O₃关键前体物!
在大气臭氧(O₃)污染已成为制约我国环境空气质量改善的核心瓶颈的当下,精准识别O₃生成的关键前体物(NOₓ与VOCs),是制定科学减排策略、破解“臭氧污染成因复杂、控制因子难辨”困境的核心前提。EKMA曲线作…...
杰理AD14N/AD15N---自定义GPIO唤醒与长按键开关机配置实战
1. 认识杰理AD14N/AD15N的GPIO唤醒机制 第一次接触杰理AD14N/AD15N芯片的开发者,往往会被其GPIO唤醒机制搞得一头雾水。我刚开始调试时也踩过不少坑,比如明明按照手册配置了唤醒引脚,设备却怎么都唤不醒。后来才发现,问题出在对底…...
