【Redis-08】Redis主从复制的实现原理

 在Redis中,可以通过slaveof命令或者设置slaveof选项实现两台Redis服务器的主从复制,比如我们有两个Redis机器,地址分别是 127.0.0.1:6379 和 127.0.0.1:6380,现在我们在前者上面执行:

127.0.0.1:6379 > SLAVEOF 127.0.0.1:6380

 那么,127.0.0.1:6379就会成为从服务器,127.0.0.1:6380就是主服务器,主从服务器通过复制会保存相同的数据,这就是数据库状态一致。今天我们探讨的重点是,主从服务器之间是如何实现数据复制的,以及slaveof这个命令的实现原理。

1.全量复制功能的实现

 主从复制的实现是通过两个操作来实现的,分别是同步(sync)和命令传播(propagate),我们看着这两个操作代表什么含义:

  • 同步:将从服务器的状态更新至主服务器当前所处的数据库状态;这里会通过一个SYNC命令来完成,具体如下:
    1. 从服务器发送SYNC命令给主服务器;
    2. 主服务器接收到命令,执行bgsave命令,创建RDB文件;
    3. 主服务器记录bgsave命令执行期间处理的客户端新命令,并写入到某个缓冲区中;
    4. RDB文件创建完成,主服务器发送给从服务器,从服务器完成RDB文件的载入;
    5. 主服务器将命令缓冲区的内容发给从服务器,从服务器执行所有命令;
    6. 从服务器状态与主服务完成数据库状态一致。
      在这里插入图片描述
  • 命令广播:主服务器会将自己执行的写命令,发送给从服务器执行,使得两者再次保持状态一致。

2.增量复制功能的实现

 主从复制分为初始化复制和断线后复制,即从服务器初始启动时,执行saveof命令会执行一次同步,还有从服务器断线后再次链接,也会执行一次同步。

 在早起的Redis的版本中,无论是首次启动还是断线后重连,都是适用SYNC命令实现,即:全量复制,但是SYNC是一个特别耗费资源的操作,会占用大量CPU、内存、网络和磁盘I/O的资源,所以在后期的版本中,是使用增量复制PSYNC来实现复制操作的。

PSYNC这个命令是同时具有完整同步和部分重同步的功能,其中完整同步的功能和SYNC命令执行的步骤一样,而部分重同步的功能是在服务器断线重连后,如果条件允许,主服务器将断线期间的命令发送给从服务器执行,达到状态的同步的目的。所以这种部分重同步的操作相对于完整同步,是能减少很多资源消耗的。

2.1 部分重同步的实现细节

 部分重同步的功能是通过3个部分构成的,分别是主从服务器两者的复制偏移量,主服务器的复制积压缓冲区,服务器的运行ID。

2.1.1 复制偏移量

 复制的双方,分别会维护一个复制的偏移量:

  • 主服务器的复制积压缓冲区每次向从服务器传播N个字节时,就会将自己的复制偏移量 +N;
  • 从服务器在接收到N个字节数据时,会将自己的复制偏移量 +N。

 这样复制的双方就可以通过复制偏移量,达到同步的目的。如果主从服务器的状态一致,那么他们的复制偏移量总是相同的,否在是处于状态不一致的情况。

2.1.2 复制积压缓冲区

 复制积压缓冲区是由主服务器维护的一个固定长度先进先出的队列,默认大小是1MB。当服务器向从服务器传播命令时,它还会将此命令入队到复制积压缓冲区里面。同时,复制积压缓冲区会为入队的每一个字节记录相应的复制偏移量值,这里的偏移量和2.1.1维护的偏移量值是相匹配。同时由于固定队列先进先出的特性,使得复制积压缓冲区中,仅保存最近一段时间执行的同步命令。

 当服务器连接到主服务器时,从服务器向主服务器发送PSYNC命令是会带上自己的复制偏移量offset,主服务器根据此偏移量决定执行哪种操作:

  • 如果从服务器偏移量offset之后的数据还保存在主服务器的复制积压缓冲区里面,那么主服务器会执行部分重同步的操作。
  • 如果从服务器偏移量offset之后的数据已经不在主服务器的复制积压缓冲区里面了,那么主服务器会执行完整同步的操作。

 所谓的部分重同步操作,是指主服务器将从服务器偏移量offset之后的所有命令发给从服务器,避免全部命令重新发送的问题。

2.1.3 服务器运行ID

 每个Redis服务器(包括主从),都会有自己的运行ID,主从服务器首次进行同步时,主服务器会将自己的运行ID发送给从服务器,从服务器会保存此ID。
 当从服务器断线重连后,想要执行复制操作,会将前面保存的服务器ID发送给主服务器,此时由主服务器执行判断:

  • 如果从服务器保存的此ID和自己的ID相同,那说明断线前后的主服务器是同一个,此时就会根据偏移量判断是执行全部同步还是部分重同步。
  • 如果从服务器保存的此ID和自己的ID不同,那说明断线前后的主服务器已经变了,此时就会执行完整同步的操作。

3.心跳检测

 在主从复制的命令传播期间,从服务器会以每秒一次的频率,向主服务器发送命令:

REPLCONF ACK <replication_offset>

 其中,replication_offset是服务器当前的复制偏移量。那么发送此命令的作用是什么呢,主要是下面三个:

  1. 检测主从服务器之间的网络连接状态: 如果主服务器在超过1s内未收到从服务器发送的命令,就会认为两者之间的网络连接出现问题了。
  2. 辅助实现min-slaves选项: 在配置文件中,有这么两个参数,min-replicas-to-writemin-replicas-max-lag,如下,如果我们开启了此选项,表示如果从服务器数量少于3个,或者三个主从服务器之间的复制延迟都大于等于10s时,主服务器将拒绝执行写命令,这里主要是为了防止主服务器在不安全的情况下执行写命令。
# 从服务器的数量是3个
min-replicas-to-write 3 
# 主从服务器之间的延迟时间,单位是3
min-replicas-max-lag 10
  1. 检测广播命令是否丢失: 在命令广播期间,因为网路问题可能存在命令在半路丢失的情况,所以通过此命令的 replication_offset,即从服务器的复制偏移量,主服务器就可以获悉从服务器是否成功执行了上一次发送的命令。如果主从的复制偏移量相等,说明命令传播没有问题,如果不相等,说明命令有丢失或从服务器执行失败的情况,此时主服务器就会把从服务器偏移量之后的命令从新发送给从服务器执行,保证两个服务器状态的一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/588501.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DDD系列 - 第8讲 仓库Repository - JPA篇(二)

目录 三、领域层定义仓库Repository接口3.1 ID生成策略3.2 内置方法的使用3.3 关于Specification的使用3.4 通过方法名定义查询3.5 自定义SQL(跨聚合)3.5.1 @NameQuery & @NamedNativeQuery3.5.2 @Query3.5.3 @Query.nativeQuery3.5.4 @Query & @Modifying3.5.5 @Que…

图片预览 element-plus 带页码

vue3、element-plus项目中&#xff0c;点击预览图片&#xff0c;并显示页码效果如图 安装 | Element Plus <div class"image__preview"><el-imagestyle"width: 100px; height: 100px":src"imgListArr[0]":zoom-rate"1.2":max…

Oracle字符串-日期转换

一、TO_CHAR日期转换为字符串 1、取得当前日期是本月的第几周 。 select to_char(sysdate,YYYYMMDD W HH24:MI:SS) from dual; select TO_CHAR(SYSDATE,YY) from dual; select to_char(sysdate,W) from dual; SQL> select to_char(sysdate,YYYYMMDD W HH24:MI…

[蓝桥杯 2018省赛]回家路费

回家路费 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明被不明势力劫持。后莫名其妙被扔到 X 星站再无问津。小明得知每天都有飞船飞往地球&#xff0c;但需要 108108 元的船票&#xff0c;而他却身无分文。…

菜鸟学习vue3笔记-vue hooks初体验

import { ref } from "vue"; export default function () {let a1 ref(1);let a2 ref(5);let c ref(0);function add() {a1.value;a2.value;}return {add,a1,a2,c,}; }<template><div><p>第一个数字{{ a1 }}</p><p>第二个数字{{ a2…

公共用例库计划--个人版(一)

1、公共用例库计划 1.1、目标 在公司测试管理体系的演变过程中&#xff0c;从禅道过渡到devops再到云效平台&#xff0c;我们已经实现了对bug和用例的有效集中管理。然而&#xff0c;在实际操作中发现&#xff0c;尽管用例管理得到了初步整合&#xff0c;但在面对不同系统和测…

离线语音识别 sherpa-ncnn 尝鲜体验

文章目录 1、ubuntu 编译运行依赖安装下载与编译模型下载运行 2、树莓派 4B 编译运行确认树莓派 4B 环境交叉编译交叉编译模型下载与运行模型对比测试树莓派 4B 运行大模型 Sherpa-NCNN 是一个基于 C 的轻量级神经网络推理框架&#xff0c;是 kaldi 下的一个子项目&#xff0c;…

Python高级并发编程的实例详解

更多Python学习内容&#xff1a;ipengtao.com Python中的高效并发编程&#xff0c;有几个重要的概念和工具可以帮助大家充分利用多核处理器和提高程序性能。本文将介绍一些关键的概念和示例代码&#xff0c;以帮助大家更好地理解Python中的高效并发编程。 多线程 vs. 多进程 在…

计算机网络【HTTP 面试题】

HTTP的请求报文结构和响应报文结构 HTTP请求报文主要由请求行、请求头、空行、请求正文&#xff08;Get请求没有请求正文&#xff09;4部分组成。 1、请求行 由三部分组成&#xff0c;分别为&#xff1a;请求方法、URL以及协议版本&#xff0c;之间由空格分隔&#xff1b;请…

使用 HarperDB SDK for Java 简化数据库操作

在现代应用程序开发的动态环境中&#xff0c;与数据库的高效、无缝交互至关重要。HarperDB 凭借其 NoSQL 功能&#xff0c;为开发人员提供了强大的解决方案。为了简化这种交互&#xff0c;HarperDB SDK for Java提供了一个方便的接口&#xff0c;用于将 Java 应用程序与 Harper…

YHZ010 Python 的类型转换

&#x1f436; 类型转换 资源编号&#xff1a;YHZ010 配套视频&#xff1a;https://www.bilibili.com/video/BV1zy4y1Z7nk?p11 &#x1f439; 检查变量类型 在 Python 中可以使用type函数对变量的类型进行检查。程序设计中函数的概念跟数学上函数的概念是一致的&#xff0c;数…

全栈架构:从0开始,Vue的搭建与开发

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;很多小伙伴拿到一线互联网企业、上市企业如阿里、网易、有赞、希音、百度、滴滴的面试资格。 然后&#xff0c;很多小伙伴平时聚焦CRUD&#xff0c;没有亮点项目&#xff0c; 黄金项目。 简历也写得是非常lo…

九台虚拟机网站流量分析项目启动步骤

文章目录 零、操作概述一、服务器分配二、9台虚拟机相互免密登录三、Nginx(反向代理服务器)四、Tomcat(Web服务器)五、测试Nginx反向代理是否成功六、Flume集群配置七、修改LogDemo项目八、项目1703FluxStorm九、Hadoop集群十、整个集群的启动十一、部署项目十二、测试项目…

骑砍战团MOD开发(26)-系统定制UI资源替换

一.TaleWorlds开机动画删除 骑砍1战团:taleworlds_intro.bik 重命名为 taleworlds_intro_bak.bik 骑砍2霸主: Modules\Native\Videos\TWLogo_and_Partners.ivf 重命名为 TWLogo_and_Partners_bak.ivf Modules\Native\Videos\TWLogo_and_Partners.ogg 重命名为TWLogo_and_Partne…

Generalized Focal Loss V1论文解读

摘要 单级检测器基本上将物体检测表述为密集分类和定位&#xff08;即边界框回归&#xff09;。分类通常通过Focal Loss进行优化&#xff0c;而边界框的定位通常根据Dirac delta分布进行学习。单级检测器的最新趋势是引入一个单独的预测分支来估计定位质量&#xff0c;预测质量…

【Web2D/3D】SVG(第二篇)

1. 前言 SVG&#xff08;Scalable Vector Graphics&#xff0c;可缩放矢量图形&#xff09;是一种使用XML描述2D图形的语言&#xff0c;由于SVG是基于XML&#xff08;HTML也是基于XML的&#xff09;&#xff0c;因为SVG DOM中每个元素都是可以操作的&#xff0c;包含修改元素属…

【javaSE】代理并不难

代理&#xff1a; 代理模式最主要的就是在不改变原来代码&#xff08;就是目标对象&#xff09;的情况下实现功能的增强 在学习AOP之前先了解代理&#xff0c;代理有两种&#xff1a;一种是动态代理&#xff0c;一类是静态代理。 静态代理 相当于是自己写了一个代理类&#…

SAP-PP:Phantom Assembly 虚拟装配 概念理解

文章目录 前言一、Phantom assembly 是什么&#xff1f;二、举例总结 前言 最近在学习PP的过程中遇到一个校验增强&#xff0c;系统中将对生产订单的组件预留进行校验&#xff0c;是否消耗正常。 那么就遇到BOM中设定了虚拟装配件的标识预留&#xff0c;其是不消耗数量的&…

力扣(leetcode)第257题二叉树的所有路径(Python)

257.二叉树的所有路径 题目链接&#xff1a;257.二叉树的所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出…

win10和win11上解决乱码的一个优点偏门的方法,不算很完美

左下角搜索控制面板&#xff0c;进入控制面板之后&#xff0c;点击时钟和区域下面的更改日期、时间或数字格式 点击顶上的“管理”选项&#xff0c;然后找到更改系统区域设置&#xff0c;把下方的Beta版&#xff1a;使用Unicode UTF-8提供全球语言支持&#xff08;U&#xff…