【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,一经查实,立即删除!

相关文章

图片预览 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…

菜鸟学习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;但在面对不同系统和测…

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

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

计算机网络【HTTP 面试题】

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

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

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

Generalized Focal Loss V1论文解读

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

【javaSE】代理并不难

代理&#xff1a; 代理模式最主要的就是在不改变原来代码&#xff08;就是目标对象&#xff09;的情况下实现功能的增强 在学习AOP之前先了解代理&#xff0c;代理有两种&#xff1a;一种是动态代理&#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…

视频批量转码:一键转换多个视频mp4格式到FLV视频

在数字媒体时代&#xff0c;视频格式的多样性给处理工作带来了诸多不便。满足不同的播放需求&#xff0c;经常要视频从一种格式转换为另一种格式。其中&#xff0c;将mp4格式转换为FLV格式的需求很常见。现在一起来看下云炫AI智剪如何高效的将视频批量转码方法&#xff0c;一键…

[Angular] 笔记 21:@ViewChild

chatgpt: 在 Angular 中&#xff0c;ViewChild 是一个装饰器&#xff0c;用于在组件类中获取对模板中子元素、指令或组件的引用。它允许你在组件类中访问模板中的特定元素&#xff0c;以便可以直接操作或与其交互。 例如&#xff0c;如果你在模板中有一个子组件或一个具有本地…

\r\n和缓冲区/进度条小程序

一 前置知识 带有\n就会立马刷新缓冲区(因为显示器是行刷新)&#xff0c;\r不会刷新缓冲区 刷新的2个场景: 1 ~fflush 缓冲区中存在\r或\n --> \r fflush --> 不换行的\n) 2 ~ 文件关闭自动刷新缓冲区 倒计时小程序0-9 %-d是左对齐,%d是右对齐 倒计时小程序0-99 …

在Go中使用Goroutines和Channels发送电子邮件

学习如何使用Goroutines和Channels在Go中发送电子邮件 在现代软件开发的世界中&#xff0c;通信是一个关键元素。发送电子邮件是各种目的的常见实践&#xff0c;例如用户通知、报告等。Go是一种静态类型和编译语言&#xff0c;为处理此类任务提供了高效和并发的方式。在本文中&…

BED 文件格式 chip-seq m6a数据可视化会用到

General usage — bedtools 2.31.0 documentationhttps://bedtools.readthedocs.io/en/latest/content/general-usage.html BED格式&#xff08;Browser Extensible Data format&#xff09;是一种在生物信息学中广泛使用的文本文件格式&#xff0c;用于描述基因组上的特征和…

机器人中的数值优化之线性共轭梯度法

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》 目录 1.无约束优化方法对比 2.Hessian-vec product 3.线性共轭梯度方法的步长​编辑 4.共轭梯度…

7.10非递减子序列(LC491-M)

算法&#xff1a; 在90.子集II (opens new window)中我们是通过排序&#xff0c;再去重来达到去重的目的。 而本题求自增子序列&#xff0c;是不能对原数组进行排序的&#xff0c;排完序的数组都是自增子序列了。 肯定还是回溯算法。 画树&#xff1a; 树里面其实有两个注意…

[python]python利用pyaudio录制系统声音没有立体声混音怎么录制系统音频

当电脑没有立体声混音导致Python写代码无法使用pyaudio进行录制系统声音怎么办&#xff1f;查阅资料和安装驱动等方法都不行&#xff0c;难道没办法了吗&#xff1f;那为什么电脑其他软件可以做到呢&#xff1f;因此研究了一下pyaudio在没有立体声混音情况下确实无法录制声音&a…

SpringBoot发布项目到docker

Dockerfile FROM openjdk:11 # 作者 MAINTAINER chenxiaodong<2774398338qq.com># 安装 vim # RUN yum -y install vim# 环境变量 # 进入容器后的默认工作目录 ENV WORKPATH /usr/local/webapp ENV EXECFILE Docker2Application-0.0.1-SNAPSHOT.jarRUN mkdir -p $WORKPA…

Android Matrix画布Canvas旋转Rotate,Kotlin

Android Matrix画布Canvas旋转Rotate&#xff0c;Kotlin private fun f1() {val originBmp BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)val newBmp Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.…