当前位置: 首页 > news >正文

redis复制的设计与实现

一、复制

1.1旧版功能的实现

旧版Redis的复制功能分为 同步(sync)和 命令传播。

  • 同步用于将从服务器更新至主服务器的当前状态。
  • 命令传播用于 主服务器状态变化时,让主从服务器状态回归一致。

1.1.1同步

当客户端向服务端发送slaveof命令,要求从服务器复制主服务器时,首先从服务器需要进行同步操作。

同步操作需要 从服务器向主服务器发送 SYNC命令 来完成,以下是SYNC命令的执行步骤。

  1. 从服务器向主服务器发送 SYNC命令
  2. 收到SYNC命令后,主服务器执行BGSAVE命令,在后台生成RDB命令,并且使用一个 缓冲区 记录从现在开始执行的所以写命令。
  3. BGSAVE命令执行完毕是,主服务器讲生成的RDB文件发送给从服务器,从服务器接收并载入。
  4. 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些命令。最终达到同步效果。

注意:在开始执行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)]

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的复制功能分为 同步&#xff08;sync&#xff09;和 命令传播。 同步用于将从服务器更新至主服务器的当前状态。命令传播用于 主服务器状态变化时&#xff0c;让主从服务器状态回归一致。 1.1.1同步 当客户端向服务端发送slaveof命令…...

Docker更换国内镜像源

什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全…...

【网络编程】网络套接字,UDP,TCP套接字编程

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 特别说明&#xff1a;本文分享的代码运行结果…...

海斯坦普Gestamp EDI 需求分析

海斯坦普Gestamp&#xff08;以下简称&#xff1a;Gestamp&#xff09;是一家总部位于西班牙的全球性汽车零部件制造商&#xff0c;目前在全球23个国家拥有超过100家工厂。Gestamp的业务涵盖了车身、底盘和机电系统等多个领域&#xff0c;其产品范围包括钣金、车身结构件、车轮…...

gpt写文章批量写文章-gpt3中文生成教程

怎么用gpt写文章批量写文章 批量写作文章是很多网站、营销人员、编辑等需要的重要任务&#xff0c;GPT可以帮助您快速生成大量自然、通顺的文章。下面是一个简单的步骤介绍&#xff0c;告诉您如何使用GPT批量写作文章。 步骤1&#xff1a;选择好训练模型 首先&#xff0c;选…...

HashMap实现原理

HashMap是基于散列表的Map接口的实现。插入和查询的性能消耗是固定的。可以通过构造器设置容量和负载因子&#xff0c;一调整容易得性能。 散列表&#xff1a;给定表M&#xff0c;存在函数f(key)&#xff0c;对任意给定的关键字值key&#xff0c;代入函数后若能得到包含该关键字…...

【Java 数据结构】PriorityQueue(堆)的使用及源码分析

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…...

使用 Kubernetes 运行 non-root .NET 容器

翻译自 Richard Lander 的博客 Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。 您可以尝试使用我们的 non-root…...

为什么大量失业集中爆发在2023年?被裁?别怕!失业是跨越职场瓶颈的关键一步!对于牛逼的人,这是白捡N+1!...

被裁究竟是因为自身能力不行&#xff0c;还是因为大环境不行&#xff1f; 一位网友说&#xff1a; 被裁后找不到工作&#xff0c;本质上还是因为原来的能力就配不上薪资。如果确实有技术在身&#xff0c;根本不怕被裁&#xff0c;相当于白送n1&#xff01; 有人赞同楼主的观点&…...

Word控件Spire.Doc 【脚注】字体(3):将Doc转换为PDF时如何使用卸载的字体

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…...

keil5使用c++编写stm32控制程序

keil5使用c编写stm32控制程序 一、前言二、配置图解三、std::cout串口重定向四、串口中断服务函数五、结尾废话 一、前言 想着搞个新奇的玩意玩一玩来着&#xff0c;想用c编写代码来控制stm32&#xff0c;结果在keil5中&#xff0c;把踩给我踩闷了&#xff0c;这里简单记录一下…...

中国社科院与美国杜兰大学金融管理硕士项目——在职读研的日子里藏着我们未来无限可能

人生充满期待&#xff0c;梦想连接着未来。每一天都可以看作新的一页&#xff0c;要努力去成为最好的自己。在职读研的光阴里藏着无限的可能&#xff0c;只有不断的努力&#xff0c;不断的强大自己&#xff0c;未来会因为你的不懈坚持而发生改变&#xff0c;纵使眼前看不到希望…...

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 域渗透工具使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、CrackMapExec 是什么&#xff1f;二、简单使用1、获取帮助信息2、smb连接执行命令3、使用winrm执行命令&#xff08;躲避杀软&#xff09;4、smb 协议常用枚…...

Modbus协议学习

以下内容从参考文章学习提炼 [参考文章](https://www.cnblogs.com/The-explosion/p/11512677.html) ## 基本概念 Modbus用的是主从通讯技术&#xff0c;主设备操作查询从设备。可以通过物理接口&#xff0c;可选用串口&#xff08;RS232、RS485、RS422&#xff09;&#xff0c…...

camunda如何处理流程待办任务

在 Camunda 中处理流程任务需要使用 Camunda 提供的 API 或者用户界面进行操作。以下是两种常用的处理流程任务的方式&#xff1a; 1、通过 Camunda 任务列表处理任务&#xff1a;在 Camunda 任务列表中&#xff0c;可以看到当前需要处理的任务&#xff0c;点击任务链接&#…...

git部分文件不想提交解决方案

正确的做法应该是&#xff1a;git rm --cached logs/xx.log&#xff0c;然后更新 .gitignore 忽略掉目标文件&#xff0c;最后 git commit -m "We really dont want Git to track this anymore!" 具体的原因如下&#xff1a; 被采纳的答案虽然能达到&#xff08;暂…...

2023年全国最新道路运输从业人员精选真题及答案58

百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 69.根据《公路水路行业安全生产风险管理暂行办法》&#xff0c;…...

Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析

Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析 漏洞简介 Zimbra是著名的开源系统&#xff0c;提供了一套开源协同办公套件包括WebMail&#xff0c;日历&#xff0c;通信录&#xff0c;Web文档管理和创作。一体化地提供了邮件收发、文件共享、协同办公、即时聊天等一系列解决…...

【数据结构初阶】第七节.树和二叉树的性质

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 一、树 1.1 树的概念 1.2 树的结点分类 1.3 结点之间的关系 1.4 树的存储结构 1.5 其他相关概念 二、 二叉树 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4…...

车载软件架构——闲聊几句AUTOSAR BSW(一)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人生是用来体验的,不是用来演绎完美的。我慢慢能接受自己身上那些灰暗的部分,原谅自己的迟钝和平庸,允许自己出错,允许自己偶尔断电,带着缺憾拼命绽放,…...

我国元宇宙行业分析:政策、技术、资金助推行业探索多元化应用场景

1.元宇宙行业概述、特征及产业链图解 元宇宙是人类运用数字技术构建的&#xff0c;由现实世界映射或超越现实世界&#xff0c;可与现实世界交互的虚拟世界&#xff0c;具备新型社会体系的数字生活空间&#xff0c;主要具有沉浸式体验、开放性、虚拟身份、不断演化、知识互动、…...

都已经那么卷了,用户还需要开源的 API 管理工具么

关于 API 管理工具&#xff0c;如今的市场已经把用户教育的差不多了&#xff0c;毫不夸张地说&#xff0c;如果我随机抽取一位幸运读者&#xff0c;他都能给我罗列出一二三四款大家耳熟能详的工具。可说到开源的 API 管理工具&#xff0c;大家又能知道多少呢&#xff1f; 我们是…...

工信部教育与考试中心-软件测试工程师考试题A卷-答

软件测试工程师考试题 姓名________________ 学号_________________ 班级__________________ 题号 一 二 三 四 五 总分 分数 说明&#xff1a;本试卷分五部分&#xff0c;全卷满分100分。考试用时100分钟。 注 意 事 项&#xff1a;1、本此考试为闭卷…...

【设计模式】模板方法模式--让你的代码更具灵活性与可扩展性

文章目录 前言模板方法模式的定义核心组成模板方法模式与其他设计模式的区别 代码实现抽象类具体类Client 经典类图spring中的例子 总结 前言 在软件开发中&#xff0c;设计模式是一种经过实践检验的、可复用的解决方案&#xff0c;它们可以帮助我们解决某一特定领域的典型问题…...

搞明白Redis持久化机制

Redis是一种内存数据库&#xff0c;其内存中的数据存储在计算机的内存中&#xff0c;如果服务器发生崩溃或者重启&#xff0c;内存中的数据将会丢失。为了避免这种情况发生&#xff0c;Redis提供了两种持久化机制&#xff1a;RDB和AOF。 一、RDB持久化 Redis支持将当前数据状…...

C# 中的正则表达式,如何使用正则表达式进行字符串匹配和替换?

在 C# 中&#xff0c;可以使用正则表达式进行字符串匹配和替换。正则表达式是一种用来描述字符串模式的语言&#xff0c;可以用来检查一个字符串是否符合某种模式&#xff0c;或者从字符串中提取符合某种模式的子串。下面我们介绍一些常用的正则表达式操作&#xff1a; 创建正…...

7年时间,从功能测试到测试开发月薪30K,有志者事竟成

突破自己的技术瓶颈并不是一蹴而就&#xff0c;还是需要看清楚一些东西&#xff0c;这里也有一些经验和见解跟大家分享一下。同样是职场人士&#xff0c;我也有我的经历和故事。在工作期间&#xff0c;我有过2年加薪5次的小小“战绩”&#xff08;同期进入公司的员工&#xff0…...

ES6 块级作用域

ES6之前没有块级作用域&#xff0c;ES5的var没有块级作用域的概念&#xff0c;只有function有作用域的概念&#xff0c;ES6的let、const引入了块级作用域。 ​ ES5之前if和for都没有作用域&#xff0c;所以很多时候需要使用function的作用域&#xff0c;比如闭包。 1.1.1 什么…...