【Redis】主从复制分析-基础

news2024/9/24 15:22:54

1 主从节点运行数据的存储

在主从复制中, 对于主节点, 从节点就是自身的一个客户端, 所以和普通的客户端一样, 会被组织为一个 client 的结构体。

typedef struct client {
    // 省略
} client;

同时无论是从节点, 还是主节点, 在运行中的数据都存放在一个 redisServer 的结构体中, 定义如下:

struct redisServer {
    // 省略
};

在主从复制中的 client 和 redisServer 都是用来存储运行中的一些数据。
具体里面存储的数据是什么, 在后面的源码分析中, 逐渐了解。

2 主从节点复制中的状态枚举

2.1 从节点自身状态的状态枚举

整个主从复制是一个复杂的过程, 所以在从节点中, 维护了一套状态, 通过状态来判断下一步的流程 (有点像状态模式)

// 没有开启主从复制功能, 默认的状态
#define REPL_STATE_NONE 0

// 开启了主从复制, 但是还没连接上主节点
// 执行了 slaveof/replicaof 命令时, 从节点的切换成的状态 
#define REPL_STATE_CONNECT 1

// 正在连接主节点, 从节点开始连接主节点
#define REPL_STATE_CONNECTING 2

/* --- 握手阶段的状态开始, 整个握手过程必须按照下面的顺序进行 --- */

// 从节点发送了 ping, 等待主节点 pong  应答 (正常情况, 主节点会回复一个 pong)
#define REPL_STATE_RECEIVE_PONG 3

// 准备发送认证密码给主节点
#define REPL_STATE_SEND_AUTH 4

// 等待主节点响应认证结果应答
#define REPL_STATE_RECEIVE_AUTH 5

// 准备发送从节点的监听的端口
#define REPL_STATE_SEND_PORT 6 

// 等待主节点响应收到从节点端口
#define REPL_STATE_RECEIVE_PORT 7

// 发送主从复制配置的监听的 IP 地址
#define REPL_STATE_SEND_IP 8 

// 等待主节点响应收到从节点的 IP 地址
#define REPL_STATE_RECEIVE_IP 9

// 准备发送从节点支持的同步能力 
#define REPL_STATE_SEND_CAPA 10 

// 等待主节点响应收到支持的同步能力的应答
#define REPL_STATE_RECEIVE_CAPA 11

// 向主节点发送 psync 命令, 请求同步复制
#define REPL_STATE_SEND_PSYNC 12 

// 等待 psync 应答
#define REPL_STATE_RECEIVE_PSYNC 13

/* --- 握手阶段的状态结束 --- */

// 正在接收从主节点发送过来的 RDB 文件
#define REPL_STATE_TRANSFER 14 

// 已经连接状态
#define REPL_STATE_CONNECTED 15 

2.2 主节点保存从节点的状态枚举

对于主节点而言, 需要知道从节点当前的状态的, 好进行对应的操作, 但是不需要那么详细, 主节点也维护了一套从节点运行时的状态


// 等待 bgsave (生成 RDB 文件的函数) 的开始
#define SLAVE_STATE_WAIT_BGSAVE_START 6

// 等待 bgsave 的结束, 也就是 RDB 文件的创建结束
#define SLAVE_STATE_WAIT_BGSAVE_END 7

// 发送一个 RDB 文件到从节点
#define SLAVE_STATE_SEND_BULK 8

// 从节点在线
#define SLAVE_STATE_ONLINE 9

3 从节点复制能力

3.1 全量复制和部分复制

整个主从复制, 大体可以概括为 3 种情况

  1. 一开始, 主从节点建立连接, 这时候主节点需要将自身所有的数据全部同步给从节点
  2. 运行中, 主节点需要将自己处理的命令, 发送一份给从节点, 这样才能保证主从的一致
  3. 运行中, 出现了网络波动, 服务重启等情况, 重新恢复正常时, 主从需要重新通过复制, 让彼此的数据重新保持一致

第一步
主从建立了连接, 主节点会将自身所有的数据生成为一个 RDB 的文件, 然后以 EOF 的流格式发送给从节点。
当然, Redis 在 2.8.18 版本开始支持无盘复制, 子进程直接将 RDB 通过网络发送给从服务器, 不使用磁盘作为中间存储。
主要是防止比较低速的磁盘, 写入缓慢, 影响到整个应用。
这个主节点将所有数据发送给从节点的操作, 叫做全量复制

第二步
在运行中, 主节点处理完了命令, 会遍历自身维护的所有的从节点, 将自身执行的命令发送给所有状态符合的从节点, 保证数据的一致。
可以看出来, 第一, 二步的操作是一个比较简单的过程, 而第三步, 在兼容性能的情况下, 将会是一个复杂的过程。

第三步
主从节点之间出现网络波动, 从节点重启等行为后, 主从之间就可能出现数据不一致。
在 Reids 2.8 版本之前, Reids 的操作就是通过在来一次全量复制, 保证了主从节点数据的一致性。

全量复制 我们可以很容易就想到这是一个耗时, 耗资源的过程, 比如 fork 子进程, RDB 文件生成, 数据发送。
所以为了尽量避免全量复制的出现, 在 Redis 2.8 版本, 引入了一个复制积压缓冲区的缓存区, 主节点执行的命令, 会先保存一份到这个缓存区
(这个缓存区是一个环形的数组, 从头写到尾, 写满了, 重新回到头, 继续写, 新的数据覆盖掉旧的, 同时所有的从节点共用一个缓冲区)。

Alt '复制积压缓冲区'

大体的实现如下

  1. 主节点启动的时候, 会生成一个 run_id (用来确保复制的主节点的唯一性)
  2. 同时生成一个复制积压缓冲区, 并且有一个变量, 记录着缓冲区中当前最旧的数据的位置, 假设为 min, 假设复制积压缓冲区的容量为 len
  3. 从节点保存着主节点生成的 run_id, 同时维持着一个变量, 当前自身最新的数据在复制积压缓冲区的哪个位置, 也就是复制偏移量, 假设为 offset
  4. 当前主从复制出现问题时, 主从重新建立连接后, 从节点会将 run_id 和 offset 发送给主节点
  5. 主节点收到后, 如果 run_id 和自身的一致, 同时 min <= offset <= min + len, 也就是需要开始复制的位置的数据, 可以在缓存区中找到, 那么从这个位置进行部分复制
  6. 主节点如果收到的 run_id 不一致, 或者 offset < min 或者 offset > min + len, 也就是需要开始复制的位置不在缓冲区中, 直接进行全量复制

Alt '部分复制过程'

这个的功能叫做 psync, 可以理解为 部分复制, 这个功能可以减少全量复制的发生。
但是这个功能有些问题, 就是从节点需要维护好 run_id, run_id 需要和从节点的一致, 同时 offset 需要在复制积压缓存中, 这其中

  1. slave 维护性重启, run_id 和 offset 会丢失
  2. 主节点故障转移, run_id 会改变
    都会导致从节点直接全量复制

所以在 Redis 4.0 针对上面的 2 种情况进行了优化, 使其在上面说的情况下, 可以进行使用部分复制, 这个升级的功能也被叫做 psync2
涉及的几个名词

  1. replid1, 每个 Redis 实例启动就会自动产生的一个 id, 这个实例变成从节点, 会被替换为主节点的 replid1
  2. replid2, 默认初始为 0, 用于存储上次主节点的 replid1

当然还要其他的情况, 会导致部分复制的失效

  1. 直接重启主节点, 这是复制积压缓冲区的数据丢了, 没法部分复制

所以 psync2 只是针对上面的 2 种情况进行了优化, 其他的情况, 还是会直接进入到全量复制

3.2 从节点重启的部分复制

在 Redis 4.0 中

  1. Redis 关闭时, 会把复制相关的信息 replid1 和 offset 作为辅助信息保存到 RDB 文件
  2. Redis 重启时, 会将从 RDB 文件中重新加载对应的复制信息到对应的字段
  3. 在进行同步时, 将 replid 和 offset 发送给主节点, 尝试进行部分复制
3.3 主节点故障转移的部分复制

当前的场景主要是在 Redis Cluster 中的故障转移情景的分析, 在直接使用主从复制中, 主节点重启, 挂了等, 都无法避免全量复制

在 Redis 4.0 中

  1. 使用了 2 组 replid 和 offset
  2. 从节点也会开启复制积压缓冲区功能, 以便从节点故障切换变化为主节点后, 其他落后的从节点可以进行同步
  3. 第一组 replid 和 offset, 如果是主节点, 表示的是自己的 replid 和复制偏移量 offset, 从节点表示的是主节点的 replid (确保级联时, replid 都是一致的) 和自身同步主节点的赋值偏移量
  4. 第二组 replid 和 offset, 无论是主从, 都表示自己的上次主节点的 replid 和 offset, 没有则默认为 0 和 -1
  5. 主节点发生了故障切换时, 会将自身的第一组 replid 和 offset 复制给第二组 replid 和 offset
  6. 这时候, 无论是一主一次还是一主多从, 都会有一个自身的从节点变为主节点, 自身变为从节点, 后面故障恢复了, 可以根据自身的第二组 replid 和 offset 进行恢复
  7. 当然不只是主从关系, 级联复制, 也适用

上面说的 3 个版本的复制能力, 在代码中分别叫做 EOF, psync1, psync2

复制能力的定义如下:

// 什么能力都不支持
#define SLAVE_CAPA_NONE 0

// 支持 EOF, 支持全量复制, 可以解析 RDB EOF 流式处理格式
#define SLAVE_CAPA_EOF (1<<0) 

// 支持 psync2, 支持部分复制
#define SLAVE_CAPA_PSYNC2 (1<<1)

对于 Redis 从节点, 可能因为版本问题, 存在着复制能力不一致的情况, 所以在主从复制开始的阶段, 从节点需要将自身支持的复制能力发送给主节点,
主节点才能以正确的方式同步数据给从节点。

4 参考

redis psync1和psync2 同步详解

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

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

相关文章

S71200 - 笔记

1 S71200 0 ProfiNet - 2 PLC编程 01.如何零基础快速上手S7-1200_哔哩哔哩_bilibili 西门子S7-1200PLC编程设计学习视频&#xff0c;从入门开始讲解_哔哩哔哩_bilibili

Facebook在内容创作中的新策略与机会

随着社交媒体的不断发展&#xff0c;内容创作已经成为了平台吸引和留住用户的核心竞争力。Facebook作为全球最大的社交平台之一&#xff0c;不断调整和优化其内容创作策略&#xff0c;以适应用户需求的变化和技术的进步。本文将深入探讨Facebook在内容创作中的新策略与机会&…

【深度学习】yolov8-det目标检测训练,拼接图的分割复原

项目背景 https://blog.csdn.net/x1131230123/article/details/140606459 似乎这个任务是简单的&#xff0c;利用目标检测是否可以完成得好呢? 生成数据集 利用这个代码产生数据集&#xff1a; 为了将标签转换为YOLOv5格式&#xff0c;需要将左上角和右下角的坐标转换为Y…

websocket实现进度条

websocket实现进度条 做一个简易的websocket实现进度条的练习&#xff0c;效果如下&#xff1a; 前端vue3 <template><el-progress type"circle" :percentage"this.progressValue" :status"this.perstatus" /><el-button cli…

【Python的wxauto】快速入门案例:简单操作微信发送消息

使用wxauto库发送消息是一个相对简单的过程。以下是一个详细的文字教程&#xff0c;以及相应的Python代码示例&#xff0c;指导您如何使用wxauto库发送消息。 文字教程&#xff1a;使用wxauto库发送消息 效果展示 步骤1&#xff1a;环境准备 确保您的计算机上安装了Python…

人工智能增强的心电图推导的身体质量指数作为未来心脏代谢疾病预测指标| 文献-基于人工智能(AI base)医学影像研究与疾病诊断

Title 题目 Artificial intelligence-enhancedelectrocardiography derived body massindex as a predictor of futurecardiometabolic disease 人工智能增强的心电图推导的身体质量指数作为未来心脏代谢疾病预测指标 01 文献速递介绍 心电图&#xff08;ECG&#xff09;可…

深度学习模型Transformer结构

Transformer结构是一种基于自注意力&#xff08;Self-Attention&#xff09;机制的深度学习模型&#xff0c;最初由Vaswani等人在2017年的论文《Attention Is All You Need》中提出&#xff0c;用于解决自然语言处理&#xff08;NLP&#xff09;领域的任务&#xff0c;如机器翻…

五年Java手,竟被一个用MemFire Cloud的前端给秒了

小李是个有五年经验的Java开发工程师&#xff0c;在公司里也算得上是技术大拿。可有一天&#xff0c;他却在一次项目竞赛中被一个刚入行不久的前端新手给秒了。这让他大感意外&#xff0c;不禁自问&#xff1a;“难道我的Java生涯要完了么&#xff1f;” 事情的真相是&#xf…

私密文件的绿色通道,使用极空间Docker部署视频文件加密工具『Alist-encrypt』

私密文件的绿色通道&#xff0c;使用极空间Docker部署视频文件加密工具『Alist-encrypt』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 关于Alist我就不用过多介绍了&#xff0c;作为多网盘存储挂载工具&#xff0c;它不仅支持文件列表全能展示&#xff0c;还可以链接分享与下载…

# Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型

Redis 入门到精通&#xff08;八&#xff09;-- 服务器配置-redis.conf配置与高级数据类型 一、redis 服务器配置–redis.conf 配置 1、服务器端设定 1&#xff09;设置服务器以守护进程的方式运行&#xff1a; daemonize yes|no 2&#xff09;绑定主机地址&#xff1a; bin…

【unity小技巧】新输入系统InputSystem重新绑定控制按键(最全最完美解决方案)

文章目录 前言安装InputSystem,并导入重新绑定控制按键例子输入控制拿例子的重绑定按钮预制体绑定对应按钮升级文本新增全屏覆盖的提示文本配置绑定绑定当前启用的输入键禁用一些按钮的绑定和退出按键绑定状态重复绑定按钮问题重置绑定重复按钮修改按钮绑定名字添加两个变量勾选…

【常见开源库的二次开发】基于openssl的加密与解密——MD5算法源码解析(五)

一、MD5算法分析 &#xff1a; 1.1 关于MD5 “消息摘要”是指MD5&#xff08;Message Digest Algorithm 5&#xff09;算法。MD5是一种广泛使用的密码散列函数&#xff0c;它可以生成一个128位&#xff08;16字节&#xff09;的散列值。 RFC 1321: MD5由Ronald Rivest在1992…

Windows 磁盘分区样式有几种?如何查看电脑分区样式?

在使用 Windows 操作系统的过程中&#xff0c;磁盘分区是一个重要的概念。磁盘分区的方式直接影响到数据存储和系统运行的效率。磁盘分区的时候也有不同的样式&#xff0c;你知道分区类型有哪些吗&#xff1f;不同的分区样式决定了硬盘的分区方式、可支持的最大存储容量以及兼容…

某企业网络及服务器规划与设计

目录 1. 项目需求与设计... 5 1.1 项目需求... 5 1.2 组建企业网络内部网的流程... 5 1) 构思阶段... 5 2) 方案设计阶段... 6 3) 工程实施阶段... 6 4) 测试验收... 6 5) 管理维护... 7 1.3 技术可行性分析... 7 1.4 网络组网规则... 8 1.5 网络拓扑... 8 2. 项目所…

气膜体育馆内运动舒服吗—轻空间

气膜体育馆作为一种新型的体育设施&#xff0c;以其灵活的结构和高效的功能受到越来越多体育爱好者的青睐。很多人可能会担心在这种环境中运动是否会感到不适。轻空间将从气膜体育馆的结构特点、环境控制和用户体验三个方面&#xff0c;详细分析在气膜体育馆内运动的舒适度。 气…

如何用JavaScript实现视频观看时间追踪

在网页开发中&#xff0c;跟踪用户与多媒体内容&#xff08;如视频&#xff09;的互动是一项常见需求。无论是教育平台、数据分析&#xff0c;还是用户参与度统计&#xff0c;监控用户如何观看视频内容都能提供宝贵的见解。这篇文章将探索如何使用JavaScript实现视频播放时长的…

win10安装ElasticSearch7.x和分词插件

说明&#xff1a; 以下内容整理自网络&#xff0c;格式调整优化&#xff0c;更易阅读&#xff0c;希望能对需要的人有所帮助。 一 安装 Java环境 ElasticSearch使用Java开发的&#xff0c;依赖Java环境&#xff0c;安装 ElasticSearch 7.x 之前&#xff0c;需要先安装jdk-8。…

飞书群聊机器人自定义机器人接入,并实现艾特@群成员功能

飞书群聊机器人还是比钉钉的要麻烦一点&#xff0c;钉钉的直接通过手机号就可以艾特群里面的人&#xff0c;但是飞书的要想艾特群里面的人&#xff0c;需要使用用户的 Open ID 或 User ID。这两个ID怎么获取呢&#xff1f;还需要在飞书的开放平台上创建一个应用&#xff0c;然后…

requets库传data和传json的区别

传data和传json的qubie 被测对象&#xff0c;白月黑羽系统 系统下载地址&#xff1a; https://www.byhy.net/prac/pub/info/bysms/ 测试用例下载地址&#xff1a; https://cdn2.byhy.net/files/selenium/testcases.xlsx 一、传data import json import requests import pytes…

废锡回收处理的生物回收法

废锡回收处理是一个复杂但重要的过程&#xff0c;它有助于节约资源、降低生产成本&#xff0c;并减少环境污染。以下是废锡回收处理的主要方法和相关细节&#xff1a; 一、废锡回收处理的主要方法 1. 化学法回收 酸浸法&#xff1a; 原理&#xff1a;通过加入适量的酸&#xff…