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

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.mzph.cn/bicheng/49190.shtml

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

相关文章

求职学习day8

7/21回顾&#xff1a; 用面试鸭的意义可能就在于将知识点用问答的形式具象化在脑海&#xff0c;不然可能只停留在听说过的感觉 7.21 玩了一天。一个很不好的信号。今天下午要试试把 mall 项目的代码运行过一遍。 项目运行问题&#xff1a; 问题 1 &#xff1a;两个门服务器…

有序充电在新型电力系统下的解决方案

摘要&#xff1a;近年来,新能源汽车的销量快速增长,相应的充电桩数量也急剧增加,这一现象可能会给电网和变压器造成负担,与此同时&#xff0c;新型电力系统下以光伏为主的分布式发电系统占比也在逐渐提高&#xff0c;新能源的不稳定性叠加充电需求的不确定性会给电网带来严峻的…

Unity发布XR中用于worldbuilding的全新电子书

通过身临其境的虚拟领域开始旅程&#xff0c;在维度之间传送&#xff0c;或将数字奇迹与现实世界融合——虚拟现实(VR)和混合现实(MR)的千万种可能性将邀请创作者把他们的想象力带入生活。 Unity发布的最新版综合指南将帮助有抱负的创作者和经验丰富的开发者深入研究和理解构建…

洛谷看不了别人主页怎么办

首先&#xff0c;我们先点进去 可以看到&#xff0c;看不了一点 那我们看向上方&#xff0c;就可以发现&#xff0c;我们那有个URL&#xff0c;选中 把光标插到n和/中间 把.cn删了&#xff0c;变成国际服 我们就可以看了 但是国际服还没搭建完&#xff0c;跳转的时候可能503&a…

融云 2024 ChinaJoy | 你有一个必逛的展位 @W4 馆 B786

惊喜闪现&#x1f447; 打开抖音搜索【融云】 关注融云官抖&#xff0c;可到展位领取好礼一份 更有惊喜内容不定时掉落~

Python从0到100(四十六):实现管理员登录及测试功能

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

“微软蓝屏”事件暴露了网络安全哪些问题?

网络安全的隐性威胁&#xff1a;从“微软蓝屏”事件看全球IT基础设施的脆弱性 ---------------------------------------------------------------------------------------------------------------------------- 一、事件回顾 近日&#xff0c;由微软视窗系统软件更新引发的…

Python设计模式:巧用元类创建单例模式!

✨ 内容&#xff1a; 今天我们来探讨一个高级且实用的Python概念——元类&#xff08;Metaclasses&#xff09;。元类是创建类的类&#xff0c;它们可以用来控制类的行为。通过本次练习&#xff0c;我们将学习如何使用元类来实现单例模式&#xff0c;确保某个类在整个程序中只…

Adobe Dimension(DN)安装包软件下载

目录 一、软件简介 二、软件下载 三、注意事项 四、软件功能 五、常用快捷键 快捷键&#xff1a; 一、软件简介 Adobe Dimension&#xff08;简称DN&#xff09;是Adobe公司推出的一款三维设计和渲染软件。与一般的3D绘图软件相比&#xff0c;DN在操作界面和功能上有所不…

国产JS库(js-tool-big-box)7月度总结

js-tool-big-box开发已经有3个月了&#xff0c;团队内的小伙伴进行了热烈的讨论&#xff0c;持续做了功能迭代。小伙伴们也做了艰苦卓绝的文档分享&#xff0c;有纯功能分享类的&#xff0c;有带有小故事的&#xff0c;有朋友们利用自己独自网站分发分享的。7月份快要结束了&am…

sip六大头域深度解析 - Max-Forwards头域

SIP&#xff08;Session Initiation Protocol&#xff0c;会话初始协议&#xff09;中的Max-Forwards头域是一个用于限制SIP请求消息在SIP网络中能够经过的实体&#xff08;如代理服务器、gateway&#xff09;的最大数目的头域。 基本概念 功能&#xff1a;Max-Forwards头域用…

FPGA DNA 获取 DNA_PORT

FPGA DNA DNA 是 FPGA 芯片的唯一标识&#xff0c; FPGA 都有一个独特的 ID &#xff0c;也就是 Device DNA &#xff0c;这个 ID 相当于我们的身份证&#xff0c;在 FPGA 芯片生产的时候就已经固定在芯片的 eFuse 寄存器中&#xff0c;具有不可修改的属性。在 xilinx 7series…

基于java 精品课程教学网站的设计与实现

1 引言 当今时代是飞速发展的信息时代。在各行各业中离不开信息处理&#xff0c;计算机被广泛应用于B/S系统环境。计算机的好处在于它能够进行信息管理。使用计算机进行信息控制&#xff0c;不仅提高了工作效率&#xff0c;而且大大的提高了安全性。 对于复杂的信息管理&…

算法——滑动窗口(day7)

904.水果成篮 904. 水果成篮 - 力扣&#xff08;LeetCode&#xff09; 题目解析&#xff1a; 根据题意我们可以看出给了我们两个篮子说明我们在开始采摘到结束的过程中只能有两种水果的种类&#xff0c;又要求让我们返回收集水果的最大数目&#xff0c;这不难让我们联想到题目…

Stateflow中的状态转换表

状态转换表是表达顺序模态逻辑的另一种方式。不要在Stateflow图表中以图形方式绘制状态和转换&#xff0c;而是使用状态转换表以表格格式表示模态逻辑。 使用状态转换表的好处包括&#xff1a; 易于对类列车状态机进行建模&#xff0c;其中模态逻辑涉及从一个状态到其邻居的转换…

软件测试09 自动化测试技术(Selenium)

重点/难点 重点&#xff1a;理解自动化测试的原理及其流程难点&#xff1a;Selinum自动化测试工具的使用 目录 系统测试 什么是系统测试什么是功能测试什么是性能测试常见的性能指标有哪些 自动化测试概述 测试面临的问题 测试用例数量增多&#xff0c;工作量增大&#xff…

ROS2入门到精通—— 1-7 ROS2实战:行为树详解

1 行为树简介 行为树&#xff1a;一种用于描述和执行复杂系统中行为的图形化结构&#xff0c;Nav2中&#xff0c;行为树用于定义机器人导航的决策和行为 &#xff08;1&#xff09;一个名为 "tick "的信号被发送到树的根部&#xff0c;并在树中传播&#xff0c;直到它…

七天打造一套量化交易系统:Day2-量化交易策略基本模型及要点

七天打造一套量化交易系统&#xff1a;Day2-量化交易策略基本模型及要点 前期回顾趋势型策略模型原理收益分布重点&#xff1a;什么因素能改进策略&#xff08;截断亏损&#xff0c;让利润奔跑&#xff09;要点总结 均值回复型策略模型原理收益分布重点&#xff1a;避免大额亏损…

智能优化算法之灰狼优化算法(GWO)

智能优化算法是一类基于自然界中生物、物理或社会现象的优化技术。这些算法通过模拟自然界中的一些智能行为&#xff0c;如遗传学、蚁群觅食、粒子群体运动等&#xff0c;来解决复杂的优化问题。智能优化算法广泛应用于各种工程和科学领域&#xff0c;因其具有全局搜索能力、鲁…

实验三 FPGA使用Verilog HDL设计加法器

实验目的 掌握使用Vivado软件进行设计、综合、仿真、布线的方法。掌握FPGA程序的下载方法。掌握使用Verilog HDL设计加法器的方法。 实验要求 采用Verilog HDL语言设计加法器&#xff0c;实现两个4位数的相加运算&#xff0c;并将结果通过LED灯或数码管显示出来。对设计进行综…