一文看懂 Redis 主从同步的原理

news2024/9/24 7:15:49

Redis 主从同步的基本原理有三种,分别是:全量复制,基于长链接的命令传播,增量复制。

接下来分别说说这三种主从间同步的原理。

全量复制

当我们启动多个 Redis 实例的时候,它们相互之间就可以通过 replicaof(Redis 5.0 之前使用 slaveof)命令形成主库和从库的关系,之后会按照三个阶段完成数据的第一次同步。

例如,现在有实例 1(ip:172.23.52.3)和实例 2(ip:172.23.52.5),我们在实例 2 上执行以下这个命令后,实例 2 就变成了实例 1 的从库,并从实例 1 上复制数据:

replicaof  172.23.52.3  6379

接下来接收三个阶段:

首先看下边这张图:

img

第一阶段是主从库间建立连接、协商同步的过程,主要是为全量复制做准备。在这一步,从库和主库建立起连接,并告诉主库即将进行同步,主库确认回复后,主从库间就可以开始同步了。

具体来说,从库给主库发送 psync 命令,表示要进行数据同步,主库根据这个命令的参数来启动复制。 psync 命令包含了主库的 runID复制进度 offset 两个参数。

  • runID,是每个 Redis 实例启动时都会自动生成的一个随机 ID,用来唯一标记这个实例。当从库和主库第一次复制时,因为不知道主库的 runID,所以将 runID 设为“?”。
  • offset,此时设为 -1,表示第一次复制。

主库收到 psync 命令后,会用 FULLRESYNC 响应命令带上两个参数:主库 runID 和主库目前的复制进度 offset,返回给从库。从库收到响应后,会记录下这两个参数。

FULLRESYNC 响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库。

第一阶段说完了,接下来说第二个阶段:

第二个阶段,主库将所有数据同步给从库。从库收到数据后,在本地完成数据加载。这个过程依赖于内存快照生成的 RDB 文件。

具体来说,主库执行 bgsave 命令,生成 RDB 文件,接着将文件发给从库。从库接收到 RDB 文件后,会先清空当前数据库,然后加载 RDB 文件。这是因为从库在通过 replicaof 命令开始和主库同步前,可能保存了其他数据。为了避免之前数据的影响,从库需要先把当前数据库清空

最后,也就是第三个阶段,主库会把第二阶段执行过程中新收到的写命令,再发送给从库。具体的操作是,当主库完成 RDB 文件发送后,就会把此时 replication buffer 中的修改操作发给从库,从库再重新执行这些操作。这样一来,主从库就实现同步了。

这是全量复制

在介绍第二种主从间同步的方式之前,先说说主从之间级联模式分担全量复制时的主库开销

在全量复制的时候,主库会生成 RDB 快照,然后在发送给从库,这些都是消耗系统资源的行为,可以想一下,如果主库的从库越来越多,那么在做全量复制的时候主库压力会非常的大。

主从级联模式就很好的将这个问题解决了。

在刚才介绍的主从库模式中,所有的从库都是和主库连接,所有的全量复制也都是和主库进行的。现在,我们可以通过**“主 - 从 - 从”模式将主库生成 RDB 和传输 RDB 的压力,以级联的方式分散到从库上。**

简单来说,我们在部署主从集群的时候,可以手动选择一个从库(比如选择内存资源配置较高的从库),用于级联其他的从库。然后,我们可以再选择一些从库(例如三分之一的从库),在这些从库上执行如下命令,让它们和刚才所选的从库,建立起主从关系。

replicaof  所选从库的IP 6379

这样一来,这些从库就会知道,在进行同步时,不用再和主库进行交互了,只要和级联的从库进行写操作同步就行了,这就可以减轻主库上的压力,如下图所示:

img

一旦主从库完成了全量复制,它们之间就会一直维护一个网络连接,主库会通过这个连接将后续陆续收到的命令操作再同步给从库,这个过程也称为基于长连接的命令传播,可以避免频繁建立连接的开销。

长链接是基于网络的,那么它就存在网络断开的风险,那么网络断开的时候怎么办呢?

在 Redis 2.8 之前,如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大。

从 Redis 2.8 开始,网络断了之后,主从库会采用增量复制的方式继续同步。听名字大概就可以猜到它和全量复制的不同:全量复制是同步所有数据,而增量复制只会把主从库网络断连期间主库收到的命令,同步给从库。

增量复制核心在于 repl_backlog_buffer 这个缓冲区

当主从库断连后,主库会把断连期间收到的写操作命令,写入 replication buffer,同时也会把这些操作命令也写入 repl_backlog_buffer 这个缓冲区。

这个缓冲区不论主库有多少个从库,它只有一个,是唯一的,不像是 replication buffer 那样每个从库都有一个,一一对应,主库从库的偏移量也都在这个缓冲区里面。

repl_backlog_buffer 是一个环形缓冲区,主库记录自己写到的位置,从库也记录自己读到的位置。

img

主从库的连接恢复之后,从库首先会给主库发送 psync 命令,并把自己当前的 slave_repl_offset 发给主库,主库会判断自己的 master_repl_offset 和 slave_repl_offset 之间的差距。

在网络断连阶段,主库可能会收到新的写操作命令,所以,一般来说,master_repl_offset 会大于 slave_repl_offset。此时,主库只用把 master_repl_offset 和 slave_repl_offset 之间的命令操作同步给从库就行。

不过,有一个地方要强调一下,因为 repl_backlog_buffer 是一个环形缓冲区,所以在缓冲区写满后,主库会继续写入,此时,就会覆盖掉之前写入的操作。如果从库的读取速度比较慢,就有可能导致从库还未读取的操作被主库新写的操作覆盖了,这会导致主从库间的数据不一致。 可以调整 repl_backlog_size 这个参数。这个参数和所需的缓冲空间大小有关。

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

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

相关文章

新人转行IC该怎么选择岗位?(内附各岗位学习视频)

最近看到不少同学在后台提问:新人转行IC该怎么选择岗位?其实转行本身就是一件大事,转行之前一定要做好调研,选择适合自己的岗位,这样才能规划好职业生涯。 IC行业这几个岗位是最常见的:数IC前端设计工程师…

PoolFormer实战:使用PoolFormer实现图像分类任务(二)

文章目录训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整算法设置混合精度,DP多卡,EMA定义训练和验证函数训练函数验证函数调用训练和验证方法运行以及结果查看测试热力图可视化展示完…

JSON数据解析

1.基础 JSON(JavaScript Object Notation) 是一种通用的轻量级数据交换文本格式。它很容易让人阅读和编写,也便于机器进行解析和生成。它使用JavaScript语法来存储和描述数据对象,但是JSON完全独立于JavaScript。JSON可适用于多种流行编程语言。这些特性…

JavaScript 用法

文章目录JavaScript 用法<script><script><script> 标签<body><body><body> 中的 JavaScriptJavaScript 函数和事件在 <head><head><head> 或者 <body><body><body> 的JavaScript<head><hea…

计算机网络知识解析

本篇文章主要讲的是计算机网络相关的内容&#xff0c;需要有一定的计算机网络的基础知识才能汲取更多的知识。当然没基础也可以看懂&#xff0c;会对计算机网络有一个基础的理解。在这一篇介绍中&#xff0c;我尽可能的覆盖一些面试中的问题&#xff0c;通过本篇文章&#xff0…

2022年吃瓜事件拆解,打造爆款,让你拥有顶级营销思维!

大环境下&#xff0c;谁又是幸存者&#xff1f;2022年吃瓜事件拆解&#xff0c;打造爆款&#xff0c;让你拥有顶级营销思维&#xff08;完整版&#xff09;&#xff01;小伍带你了解【商业营销内核】&#xff01;咱们开讲&#xff01;【事件1】张兰 vs 大S&#xff0c;大女主张…

【PyTorch学习1】B站刘二大人《PyTorch深度学习实践》——线性模型(Linear Model)

b站课程链接&#xff1a;线性模型 1.基本思想&#xff1a; 给出了一组一维数据&#xff0c;定义了一个简单的线性拟合函数&#xff0c;通过穷举法来列出一些权重&#xff08;拟合函数的系数&#xff09;&#xff0c;并计算这些权重对应的拟合损失函数&#xff08;使用均方误差…

C/C++智能指针详解

系列文章目录 文章目录系列文章目录前言一、什么是智能指针&#xff1f;二、使用方法1.shared_ptr2.unique_ptr3.weak_ptr前言 对C/C学习感兴趣的可以看看这篇文章哦&#xff1a;C/C教程 本章主要介绍一些C/C中智能指针的实现原理以及如何使用 一、什么是智能指针&#xff1…

计算机组成原理复习:存储器系统

计算机组成原理复习&#xff1a;存储器系统3.1 存储器的层次化结构3.2 半导体随机存储器&#xff08;RAM&#xff0c;易失性存储器&#xff09;3.2.1 静态随机存储器&#xff08;SRAM&#xff09;3.2.2 动态随机存储器&#xff08;DRAM&#xff09;3.2.3 只读存储器&#xff08…

token认证、Express中实现token的过程

一、token认证 1. 什么是token token的意思是“令牌"&#xff0c;是服务端生成的一串字符串&#xff0c;作为客户端进行请求的一个标识。当用户第一次登录后&#xff0c;服务器生成一个token并将此token返回给客户端&#xff0c;以后客户端只需带上这个token前来请求数据…

Jenkins搭建 笔记总结

文章目录1. 什么是CI/CD(DI)&#xff1f;2. 环境 安装部署3. 搭建 GitLab服务器&#xff08;ssh方式搭建&#xff09;4. 搭建 GitLab服务器&#xff08;Docker方式搭建&#xff09;4.1 搭建Docker环境4.2 docker容器 安装gitlab5. GitLab 提交代码6. Jenkins 配置Maven Git自动…

【信息论与编码 沈连丰】第五章:离散信道及其信道编码

【信息论与编码 沈连丰】第五章&#xff1a;离散信道及其信道编码第五章 离散信道及其信道编码5.1 信道的分类及其描述5.2 无扰离散信道的传输特性5.3 有扰离散信道的传输特性5.4 译码准则5.5 有扰离散信道的信道编码定理5.6 信道编码定理的应用第五章 离散信道及其信道编码 5…

6\8. 语义分析和中间代码生成

6&8. 语义分析和中间代码生成 从几个问题说起&#xff1a; 要计算 34*5 的值如何计算&#xff1f;按照以前的方法&#xff0c;我们会想到利用符号栈和数值栈来完成这个运算。但是有了语法分析之后我们不再需要进行这么复杂的代码构造了。第一&#xff0c;我们可以使用自顶…

AcWing1206.剪格子——学习笔记(未AC)

题目&#xff1a;1206. 剪格子 - AcWing题库https://www.acwing.com/problem/content/description/1208/ import java.util.Scanner;public class Main {public static void main(String args[]){//读数据Scanner input new Scanner(System.in);String MN input.nextLine();S…

Apache ShardingSphere分表的简单使用和常见问题

目录 简介 什么是 Apache ShardingSphere? 分库分表的背景 使用 pom 配置 1&#xff0c;application.properties配置文件 2&#xff0c;创建配置类 分表 验证分表 常见问题 自定义分表规则未生效 简介 官网&#xff1a;Apache ShardingSphere 版本&#xff1a;4…

ArcGIS基础实验操作100例--实验42创建渔网Fishnet

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验42 创建渔网Fishnet 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&a…

深度学习推理框架调研总结

深度学习推理框架1.移动端深度学习推理框架调研1.1 小米的MACE&#xff08;2017&#xff09;1.2 阿里的MNN1.3 腾讯的TNN1.4 ARM的tengine1.5 百度的paddle-mobie1.6 Facebook的Caffe2&#xff08;*&#xff09;1.7 Google的TensorFlow Lite &#xff08;*&#xff09;1.8 Appl…

南京晓庄操作系统期末复习【背诵部分】

操作系统期末复习背诵部分第一章1.操作系统的特征&#xff1a;2.操作系统的最基本特征是什么&#xff0c;为什么3.操作系统的目标4.操作系统的主要功能5.计算机资源6.多道程序设计时应解决什么问题7.三种操作系统及特点第二章1.进程的定义2.进程的特征3.进程的三种基本状态4.进…

Spark04: Transformation与Action开发

一、创建RDD的三种方式 RDD是Spark编程的核心&#xff0c;在进行Spark编程时&#xff0c;首要任务是创建一个初始的RDD这样就相当于设置了Spark应用程序的输入源数据然后在创建了初始的RDD之后&#xff0c;才可以通过Spark 提供的一些高阶函数&#xff0c;对这个RDD进行操作&a…

python学生管理系统(pyqt5 含界面)

学生管理系统项目流程 项目模块 账号登陆 人脸识别 增添学生信息 删除学生信息 改动学生信息 查询学生信息 项目主体框架 app.py为主代码&#xff0c;负责用于界面打开展示。img文件夹负责放置项目qrc的图像page文件夹为单独页面的类plugin文件夹为功能模块的类ui文件夹…