redis复制的设计与实现

news2024/11/15 10:47:23

一、复制

1.1旧版功能的实现

旧版Redis的复制功能分为 同步(sync)和 命令传播。

  • 同步用于将从服务器更新至主服务器的当前状态。
  • 命令传播用于 主服务器状态变化时,让主从服务器状态回归一致。

1.1.1同步

当客户端向服务端发送slaveof命令,要求从服务器复制主服务器时,首先从服务器需要进行同步操作。

同步操作需要 从服务器向主服务器发送 SYNC命令 来完成,以下是SYNC命令的执行步骤。

  1. 从服务器向主服务器发送 SYNC命令
  2. 收到SYNC命令后,主服务器执行BGSAVE命令,在后台生成RDB命令,并且使用一个 缓冲区 记录从现在开始执行的所以写命令。
  3. BGSAVE命令执行完毕是,主服务器讲生成的RDB文件发送给从服务器,从服务器接收并载入。
  4. 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些命令。最终达到同步效果。

注意:在开始执行BGSAVE命令后,记录在缓冲区里的写命令并不会记录在RDB文件中。RDB中记录的是开始BGSAVE命令之前的数据,从以下例子也能看出。

1.1.2命令传播

在同步操作之后,当主服务器执行客户端发送的写命令时,主服务器的数据库可能被修改,导致主从服务器状态不一致。为了使主从的状态回归一致,主服务器需要执行 命令传播 操作。

主 会将自己执行的写命令也即造成状态不一致的命令,发送给从服务器,当从服务器执行相同写命令后,主从状态回归一致。

1.2旧版复制功能的缺陷

1.2.1从服务器对主服务器的复制的两种情况

  • 初次复制:从服务器以前没有复制过任何服务器,或者当前要复制的服务器和上次复制的主服务器不同。
  • 断线后重复制。

1.2.2 缺陷

对于初次复制的情况,旧版能很好的解决,但是对于断线后重复制,效率就非常低了。

旧版实现断线后重复制的方法是,断线重连后,又执行一遍sync命令。

但是实际上我们仅仅需要同步 断线期间主服务器执行过的写操作。而sync命令是非常耗费资源的操作!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gVH4HFnv-1682267130057)(C:\Users\chenzhengchang\AppData\Roaming\Typora\typora-user-images\image-20230423112927560.png)]

1.3新版复制功能的实现

从redis 2.8版本开始,使用 PSYNC命令 代替SYNC命令来执行复制时的同步操作。

PSYNC命令具有 完整重同步部分重同步 操作。

完整重同步用于初次复制的情况,和sync命令基本一样。

部分重同步用于断线后重复制的情况。当从服务器断线后重连,如果条件允许,主服务器将 断线期间执行的写命令发送给从服务器,从服务器接收并执行即可。

1.4部分重同步的实现

部分重同步功能由以下三个部分构成:

  • 主服务器和从服务器的 复制偏移量(replication offset) ;
  • 主服务器的 复制积压缓冲区(replication backlog)
  • 服务器的运行ID (run ID)

1.4.1复制偏移量

主从服务器都会维护一个复制偏移量:

  • 主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量加上N。
  • 从服务器每次接收到主服务器的N个字节后,就将自己的复制偏移量加上N。

对比主从服务器的复制偏移量,相同则状态一致,不同则不一致。

1.4.2复制积压缓冲区

复制积压缓冲区是主服务器维护的一个固定长度的 先进先出 队列,默认大小为1MB。

当主服务器进行命令传播时,会将写命令写入复制积压缓冲区。

主服务器的复制积压缓冲区里面保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的 复制偏移量

当从服务器重连时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器:

  • 如果offset偏移量之后的数据还在复制积压缓冲区,则进行部分重同步。
  • 否则,将执行完整重同步。

1.5PSYNC命令的实现细节

PSYNC命令的调用方法有两种

根据情况,主服务器将会有以下三种的某种回复:

  • 主服务器返回 +FULLERSYNC ,表示执行完整重同步。runid和offset是主服务器的,从服务器将会以offset作为自己的初始化偏移量。
  • 返回 +CONTINUE,表示执行部分重同步。
  • -ERR,表示主服务器的版本低于2.8,识别不了PSYNC,将执行SYNC命令。

1.6复制的实现

通过向服务器发送slaveof命令,可以让一个服务器去复制另一个服务器。

slaveof <master_ip> <master_port>

1.6.1步骤1:设置主服务器的地址和端口

从服务器将客户端给定的 主服务器IP及端口绑定到服务器的相关属性中。

slaveof命令是一个异步过程,在完成属性设置后,向发送slaveof命令的客户端返回OK。表示复制指令接收,而实际的复制工作将在O返回后才开始执行。

1.6.2步骤2:建立套接字连接

设置好IP及端口属性后,从服务器将会创建连向主服务器的套接字连接。

如果从服务器创建套接字能成功连接到主服务器,那么从服务器将会为其关联一个专门用于处理复制工作的文件事件处理器,负责后续的复制工作,比如接收RDB文件,接收主服务器传来的写命令等。

主服务器在接收(accept)从服务器的套接字连接后,将为该套接字创建相应的客户端状台3,并将从服务器看作一个连接到主服务器的客户端对待。

1.6.3步骤3,发送PING命令

从服务器成为主服务器的客户端之后,做的第一件事就是向主服务器发送 一个 PING命令

PING命令的作用:

  • 检查套接字读写状态是否正常;
  • 检查主服务器能否正常处理请求命令。

发送PING命令后将会遇见以下三种情况的一种:

  • 主服务器返回一个命令回复,但是从服务器却不能在规定时间读取出命令回复的内容,表示网络连接状态不佳,从服务器断开并重建 套接字。
  • 主服务器回复一个错误,表示主服务器暂时没办法处理从服务器的命令请求。从服务器断开并重建 套接字。
  • 从服务器读取到 “PONG”,流程继续正常进行。

1.6.4步骤4:身份验证

从服务器接收到 PONG 后下一步就是决定是否需要身份验证:

以下由流程图来说明这一过程。

1.6.5步骤5:发送端口信息

身份验证后,从服务器向主服务器发送从服务器的监听端口号。主服务器将其记录在从服务器所对应的客户端状态属性中。

1.6.6步骤6:同步

在这一步,从服务器向主服务器发送PYSNC命令,执行同步操作。

值得一提的是,在同步操作执行之前,只有从服务器是主服务器的客户端,同步操作之后,主服务器成为从服务器的客户端

1.6.7步骤7:命令传播

完成同步操作之后,主服务器就会进入命令传播阶段,只要主服务器一直将执行的写命令发送给从服务器就可以了。

1.7心跳检测

在命令传播阶段,从服务器默认以每秒一次的频率向主服务器发送命令。

REPLCONF ACK <replication_offset>

其中replication_offset是从服务器当前复制偏移量。

该命令注意有三个作用:

  • 检测主从服务器的网络连接状态
  • 辅助实现min-slaves选项
  • 检测命令丢失。

1.7.1检测主从服务器的网络连接状态

通过发送和接收 REPLCONF ACK 命令来检测网络连接是否正常。

如果主服务器超过一秒没有接收到该命令,主服务器就知道它们之间的连接出现问题了。

通过向主服务器发送 INFO replication命令,在从服务器列表的lag一栏可以看到相应从服务器最后一次向主服务器发送REPLCONF ACK 命令距离现在过了多少秒。

1.7.2辅助实现min-slaves配置选项

redis的 min-slaves-to-write 和 min-slaves-max-lag两个选项可以保证防止主服务器在不安全的情况下执行写命令。

前者表示 最小从服务器数量,后者为 最小服务器数量的延迟值需要小于多少秒。

min-slaves-to-write 3
min-slaves-max-lag 10

如果不符合,则主服务器拒绝执行写命令。

1.7.3检测命令丢失

如果复制偏移量对应不上,那么主服务器将会将复制积压缓冲区里的数据发送给从服务器,以维持状态一致。

注:本文为个人学习笔记,文章内容摘自黄健宏《Redis设计与实现》。redis的复制功能是sentinel和集群的基础之一,本文简单概括了redis复制功能的设计与实现,如果想详细了解过程建议看一下Redis设计与实现这本书,强列推荐!

大家有什么疑问可以评论或者私信,一起进步。

多机功能后面会持续更新。

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

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

相关文章

5款十分小众的软件,知道的人不多但却很好用

今天推荐5款十分小众的软件&#xff0c;知道的人不多&#xff0c;但是每个都是非常非常好用的&#xff0c;有兴趣的小伙伴可以自行搜索下载。 1.视频直播录制——OBS Studio OBS Studio可以让你轻松地录制和直播你的屏幕、摄像头、游戏等内容。你可以使用OBS Studio来创建多种…

opengl入门之创建窗口

OpenGL系列文章目录 文章目录 OpenGL系列文章目录前言GLFWGLFW Logo构建GLFWAttention编译生成的库CMake编译我们的第一个工程链接Windows上的OpenGL库Linux上的OpenGL库ImportantGLAD配置GLAD 附加资源 前言 注意&#xff0c;由于作者对教程做出了更新&#xff0c;之前本节使…

springboot使用jasper实现报表demo

概述 业务中尝尝需要用到报表数据的渲染和导出.报表的配置势必不能写死&#xff0c;需要动态配置。 现成的JasperReports Jaspersoft Studio即可实现可配置的报表。 报表布局Jaspersoft Studio https://community.jaspersoft.com/community-download 下载布局工具&#xf…

【fisco-bcos底层链】WeBASE管理平台各组件分别打包成镜像部署到k8s上亲测完成

【fisco-bcos底层链】WeBASE管理平台各组件分别打包成镜像部署到k8s上亲测完成 前言第一步、docker 打包dockerfile书写第二步、fisco-bcos 三节点的底层链1. 更改数据库连接信息2.删除节点中运行预语句中最后的的&符号3. 具体编译的dockerfile4. 编译dockerfile生成 fisco…

【Linux编程Shell自动化脚本】01 Shell 变量、条件语句及常用概念操作等详解

文章目录 一、简介二、变量详解1. 系统变量 三、If条件语句1. ()、(())、[]、[[]]、let和test的区别&#xff08;1&#xff09;bash中的Compound Commands&#xff08;2&#xff09;Shell Builtin Commands&#xff08;3&#xff09;Arithmetic Evaluation&#xff08;4&#x…

【MySQL | 进阶篇】09、MySQL 管理及常用工具(mysqladmin、mysqlbinlog、mysqldump 等)的使用

目录 一、系统数据库 二、常用工具 2.1 mysql 示例 2.2 mysqladmin 示例 2.3 mysqlbinlog 示例 2.4 mysqlshow 示例 2.5 mysqldump&#xff08;数据备份&#xff09; 示例 2.6 mysqlimport/source&#xff08;数据恢复&#xff09; 2.6.1 mysqlimport 2.6.2 …

实现表格可编辑(点击字段出现输入框)vue elementUI

实现表格可编辑 参考&#xff1a;el-table 中实现表格可编辑_el表格编辑_快乐征途的博客-CSDN博客 按行保存数据&#xff0c;每行数据最后都有一个保存按钮&#xff0c;如下图所示 使用的是<template>嵌套<el-input> 完整代码如下&#xff1a; <template>…

【计算机视觉 | 目标检测】RT-DETR:DETRs Beat YOLOs on Real-time Object Detection

文章目录 一、前言二、简介三、相关方法3.1 实时目标检测器3.2 端到端目标检测器3.3 目标检测的多尺度特征 四、检测器端到端速度4.1 分析NMS4.2 端到端速度基准 五、The Real-time DETR5.1 方法概览5.2 高效混合编码器5.2.1 计算瓶颈分析5.2.2 Hybrid design5.2.3 IoU-Aware查…

【LeetCode】105. 从前序与中序遍历序列构造二叉树

1.问题 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null…

“访达”不能完成操作,因为不能读取或写入“”中某些数据。

“访达”不能完成操作&#xff0c;因为不能读取或写入“”中某些数据。 复制文件夹时出现「“访达”不能完成该操作&#xff0c;因为不能读取或写入“”中的某些数据。 &#xff08;错误代码-36&#xff09;」及icloud中文件夹无法下载提示「未能下载项目“XX”。」 最近1个月…

1.Mybatis基本介绍

为什么使用MyBatis&#xff1f; 1.JDBC在创建Connection的时候&#xff0c;存在硬编码问题&#xff08;也就是直接把连接信息写死&#xff0c;不方便后期维护&#xff09; 2.preparedStatement对象在执行sql语句的时候存在硬编码问题 3.每次在进行一次数据库连接后都会关闭数据…

【SWAT水文模型】ArcSWAT输入准备:土地利用/土壤/气象数据

ArcSWAT输入准备&#xff1a;土地利用/土壤/气象数据 1 土地利用数据的处理1.1 数据下载 2 土壤库建立2.1 数据下载 3 气象数据库参考 1 土地利用数据的处理 1.1 数据下载 下载地址如下&#xff1a; 中科院1km土地利用数据 清华大学高精度土地利用数据 2 土壤库建立 SW…

pytest学习二(通过配置文件运行、分组执行,及其它一些参数)

接上一篇说到了环境的配置&#xff0c;以及一个用例的编写&#xff0c;接下来继续记录一些它的运行方式和一些平常使用的标签 一、通过全局配置文件&#xff08;pytest.ini&#xff09;运行 pytest.ini配置文件的编写规则 ①编码格式一般为ANSI ②一般放在项目的根目录下&a…

个人杂笔记

docker里面的-p暴露端口是确确实实写了才会映射到主机 docker run -d --hostname my-rabbit --name my-rabbit -e RABBITMQ_DEFAULT_USERroot -e RABBITMQ_DEFAULT_PASS250772730 -p 8080:8080 -p 15672:15672 -p 5672:5672 rabbitmq:3-managementpip安装提示warning 可能原因…

【 Spring Mybatis 复杂的查询操作 】

文章目录 引言一、参数占位符 #{} 和 ${}二、SQL 注入三、like 模糊查询四、返回类型&#xff1a;resultType 和 resultMap五、多表查询 引言 前面我们已经学会了使用 Mybatis 进行增&#xff0c;删&#xff0c;改操作&#xff0c;也实现了简单的查询操作 &#xff01;下面我们…

执着于考研考公却一再挫败,拿什么拯救你的职场后半生?

今天之所以想写一篇这样的文章&#xff0c;确确实实是有感而发&#xff0c;因为从近来接触的学员身上&#xff0c;能够最直观地感受到&#xff1a;考公考研失败后的同学&#xff0c;他们内心的那种焦虑感远超往期&#xff01; 用他们的话讲&#xff1a;“目前的状态就是感觉自…

540. 有序数组中的单一元素

给你一个仅由整数组成的有序数组&#xff0c;其中每个元素都会出现两次&#xff0c;唯有一个数只会出现一次。 请你找出并返回只出现一次的那个数。 你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。 示例 1: 输入: nums [1,1,2,3,3,4,4,8,8] 输出: 2 示…

“开发人员必备技能:Python接口自动化测试全攻略“:了解接口测试的基础知识,并通过Python编写测试用例,提升自己的测试技能

目录 摘要 一、基础知识 二、工具选择 三、实现步骤 1.安装依赖库 2.编写测试用例 3.运行测试用例 4.查看测试结果 四、代码实现 总结 摘要 随着互联网行业的不断发展&#xff0c;越来越多的企业开始注重自动化测试的重要性。而在自动化测试中&#xff0c;接口自动化…

同为科技(TOWE)防雷科普篇(二)——雷击灾害急救方法大全

前 言 当雷击发生时&#xff0c;空气中的各种微粒互相碰撞和摩擦便会使该空气介质两面的正负电荷的量持续积累&#xff0c;这时加于该空气介质的电压也会同时增加&#xff0c;当局部电压达到当时条件下空气的击穿电压时&#xff0c;该空气介质的局部便会发生电击穿而持续成为等…

我国激光打标机行业分析:防疫放开医疗行业激光打标机需求迫切 行业将迈向自动化、智能化的未来

1、激光打标机行业定义、分类及应用范围 激光打标机是用激光束在各种不同的物质表面打上永久标记的激光设备。激光打标技术相比传统的标识技术&#xff0c;不仅仅在对于材料的损耗&#xff0c;标识效果更具有优势&#xff0c;并且在生产加工的效率和产出方面更是有过之而无不及…