redis:主从复制

news/2024/11/21 15:20:32/

在这里插入图片描述

个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《Linux》《网络》 《redis学习笔记》

文章目录

  • 前言
  • 主从模式
  • 复制拓扑结构
  • 主从节点建立复制流程
  • 数据同步 psync
  • psync运行流程
  • 全量复制流程
  • 部分复制流程
  • 实时复制
  • 总结


前言

分布式系统,涉及到一个关键的问题:单点问题。
如果某个服务器程序,只有一个节点(只有一个物理服务器,来部署这个服务器程序);有两个问题:

  1. 可用性问题:如果这个机器挂了,意味着服务就中断了
  2. 性能/支持的并发量也是比较有限的

在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其它服务器,满足故障恢复和负载均衡等需求。redis为我们提供了复制功能,实现了相同数据的多个redis副本,复制功能是高可用redis的基础。

在分布式系统中,使用多个服务器来部署redis,存在以下几种redis的部署方式:

  1. 主从模式
  2. 主从 + 哨兵模式
  3. 集群模式

主从模式

redis的主从模式中,存在多个redis服务器节点,它们被划分为主节点(master)和从节点(slave);每个从节点只能有一个主节点,但一个主节点可以有多个从节点;从节点是主节点的副本,会同步主节点上的所有数据,同时,当主节点对数据有任何修改时,这些修改也会同步到从节点上;从节点不允许直接修改数据,所有写操作都必须通过主节点来完成

假设有三个物理服务器(三个节点),分别部署一个redis-server进程;此时就可以把其中一个节点,作为主节点;另外两个节点作为从节点
在这里插入图片描述
现在,如果挂掉了某个从节点,没什么影响,此时继续从主节点或者其它从节点读取数据得到的效果完全相同;如果挂掉主节点,还是有一定影响,不能写数据了。
所以主从模式,主要是针对 读操作 进行 并发量 和 可用性 的提高;而 写操作 无论可用性还是并发量,都非常依赖主节点


复制拓扑结构

一主一从结构是最简单的复制拓扑结构。
在这里插入图片描述
如果写数据请求太多了,此时也会给主节点造成一些压力;可以通过关闭主节点的AOF(关闭向硬盘写入),只在从节点开启AOF;
但这种设定方式,有一个严重的缺陷,主节点一旦挂了,不能让它自己重启,如果自动重启,此时没有AOF文件,就会丢失数据,进一步的主从同步,会把从节点的数据也给删除了
改进办法,当主节点挂了之后,需要让主节点在从节点这里获取到AOF的文件,在启动


一主多从结构使得应用端可以利用多个从节点实现读写分离,对于读比重较大的场景,可以把读命令负载均衡到不同的从节点上来分担压力。同时一些耗时的读命令可以指定一台专门的从节点执行,避免破坏整体的稳定性
在这里插入图片描述

但从节点过多,也会导致主节点带宽压力过大;主节点执行的写入命令需要被复制到所有的从节点,从节点数量越多,主节点需要发送的写命令次数也越多


树形主从结构(分层结构)使得从节点不但可以复制主节点数据,同时可以作为其它从节点的主节点继续向下层复制,通过引入复制中间层,可以有效降低系统按负载和需要传送给从节点的数据量

在这里插入图片描述
但子节点层数过多会对网络延迟造成影响

  • 网络传输延迟:当子节点层数过多时,数据需要经过更多的网络节点和链路
  • 子节点处理延迟:每个子节点在接受数据时都需要进行处理;当子节点层数增多时,中间节点的处理延迟会累加,进一步增加整体延迟
  • 同步效率降低:在树形结构中,如果某个中间节点出现故障或网络问题,可能会导致其下游的从节点无法及时同步数据

主从节点建立复制流程

在这里插入图片描述

  • 从节点内部通过每秒运行的定时器任务维护复制相关逻辑,当定时器发现存在新的主节点后,会尝试与主节点建立基于TCP的网络连接;如果从节点无法建立连接,定时任务会无限重试直到连接成功或者用户停止主从复制
  • 发送ping命令;连接建立成功之后,从节点通过ping命令确认主节点在应用层上是工作良好的;如果ping命令的结果pong回复超时,从节点会断开TCP连接,等待定时任务下次重新建立连接
  • 权限验证;如果主节点设置了requirepass参数,则需要密码验证,从节点通过配置masterauth参数来设置密码,如果验证失败,则从节点的复制将会停止
  • 同步数据集,对于首次建立复制的场景,主节点会把当前持有的所有数据全部发送给从节点,
  • 命令持续复制,当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点指向修改命令,保证主从数据的一致性

数据同步 psync

redis使用 psync 命令完成主从数据同步,同步过程分为:全量复制 和 部分复制

  • 全量复制:一般用于初次复制场景,会把主节点全部数据一次性发送给从节点,当数据流较大时,会对主从节点和网络造成很大的开销
  • 部分复制:用于处理在主从复制中因为网络闪断等原理造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发数据给从节点

PSYNC replicationid offset

psync不需要我们手动执行,redis服务器会在建立好主从同步关系之后,自动执行psync(从节点负责执行)


replication复制,是主节点生成的;主节点启动的时候就会生成,从节点晋升成主节点的时候也会生成,但即使是同一个主节点,每次重启,生成的replication id都是不同的。
从节点和主节点建立复制关系,就会从主节点这边获取replication id

通过info replication查看
在这里插入图片描述
每个节点都需要记录两组master_replid;

当前有两个节点A 和 B,A为master,B为slave;此时 B 就会记录 A 的 master_replid;如果网络抖动,B 认为 A挂了,B自己就会称为主节点,于是 B 给自己分配了新的master_replid;此时就会使用master_replid2来保存之前A的master_replid
如果后续网络恢复了,B就可以根据master_replid2找回之前的主节点
如果后续网络没有恢复,B就按照新的master_replid自成一派,继续处理后续的数据


offset偏移量
主节点和从节点上都会维护 偏移量(整数);

  • 主节点的偏移量:主节点会收到很多的修改操作的命令,每个命令都要占据几个字节,主节点会把这些修改命令,每个命令的字节数进行累加
  • 从节点的偏移量:现在从节点这里数据同步到哪里了

通过对比主从节点的偏移量,可以判断主从节点数据是否一致


replication id 和 offset 共同描述了一个“数据集合”;replication id相当于原地址,offset相当于大小
如果发现两个机器,replication id 和 offset都相同,就可以认为这两个redis机器上存储的数据就是完全一样的


psync运行流程

psync可以从主节点获取全量数据,也可以获取一部分数据;主要看offset的值,offset写作-1,就是获取全量数据;offset写具体的正整数,则是从当前偏移量位置来进行获取

在这里插入图片描述

  • 从节点发送psync命令给主节点,replid 和 offset的默认值分别是?和-1
  • 主节点根据psync参数和自身数据情况决定响应结果:+FULLRESYNC replid offset,则从节点需要进行全量复制流程;+CONTINEU,从节点进行部分复制流程;-ERR,redis主节点版本过低,不支持psync命令,从节点可以使用sync命令进行全量复制

什么时候进行全量复制:

  • 首次和主节点进行数据同步
  • 主节点不方便进行部分复制的时候

什么时候进行部分复制:

  • 从节点之前已经从主节点复制过数据了,因为网络抖动或者从节点重启;从节点需要重新从主节点这边同步数据;此时看能不能只同步一小部分数据

psync一般不需要手动执行,redis会在主从复制模式下自动调用执行


全量复制流程

全量复制是redis最早支持的复制方式,也是主从第一次建立复制时必须经历的阶段
在这里插入图片描述

  1. 从节点发送psync命令给主节点进行数据同步,由于是第一次进行复制,从节点没有主节点的复制ID(replid)和 复制偏移量(offset),发送 psync ? -1
  2. 主节点根据命令,解析出要进行全量复制,回复+FULLRESYNC响应
  3. 从节点接受到主节点的运行信息(包括复制ID和复制偏移量等)进行保存
  4. 主节点执行bgsave进行RDB文件持久化
  5. 主节点发送RDB文件给从节点,从节点保存RDB数据到本地硬盘
  6. 主节点将从生成RDB到接受完成期间执行的写命令,写入缓冲区中,等从节点保存完RDB文件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照RDB的二进制格式追加写入到收到的RDB文件中,保持主从一致性
  7. 从节点清空自身原有旧数据
  8. 从节点加载RDB文件得到与主节点一致的数据
  9. 如果从节点加载RDB完成之后,并且开启了AOF持久化功能,会进行bgrewrite操作,得到最近的AOF文件

注意:
主节点执行 bgsave 生成RDB文件,不能使用已有的RDB文件,而是必须重新生成一个,已有RDB文件可能会和当前最新的数据存在较大差异;


主节点进行全量复制,也支持"无硬盘模式"(diskless);
主节点生成的RDB的二进制数据,不保存到文件中,而是直接进行网络传输(避免一系列读硬盘和协硬盘的操作);从节点直接把收到的数据进行加载,避免了将收到的RDB数据,写入硬盘,然后在加载;
但即使引入了无硬盘模式,全量复制整个操作还是比较耗时的;所以一般应该尽可能避免对已经有大量数据集的redis进行全量复制


部分复制流程

从节点要从主节点这里进行全量复制,全量复制,开销很大;有些时候,从节点本身已经持有了主节点的绝大部分数据,这个时候,就不太需要进行全量复制;
部分复制主要是redis针对全量复制的过高开销做出的一种优化措施,使用 psync replicationID offset 命令实现。当从节点正在复制主节点时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区存在数据则直接发送给从节点,这样就可以保存主从节点复制的一致性;补发的这部分数据一般远远小于全量数据,所以开销很小

在这里插入图片描述

  1. 当主从节点之间出现网络中断时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接
  2. 主从连接中断期间,主节点依旧响应命令,但这些复制命令都因网络中断无法及时发送给从节点,所以暂时将这些命令滞留在复制积压缓冲区中
  3. 当主从节点网络恢复后,从节点再次连上主节点
  4. 从节点将之前保存的 复制ID(replicationId) 和 复制偏移量(offset) 作为psync的参数发送给主节点,请求进行部分复制
  5. 主节点接到 psync 请求后,进行必要的验证;随后根据 offset 去复制积压缓冲区查找合适的数据并响应+CONTINUE给从节点
  6. 主节点将需要从节点同步的数据发生给从节点,最终完成一致性

replicationId 其实就是在描述“数据的来源”;offset 描述“数据的复制进度”


复制积压缓冲区可以看成一个内存中的循环队列;会记录最近一段时间修改的数据,总量有限,随着时间的推移,就会把之前的旧的数据逐渐删除;
主节点就看offset是否在当前的复制积压缓冲区之内,如果确实在复制积压缓冲区之内,此时就可以直接进行部分复制;如果确实当前从节点的进度已经超出复制积压缓冲区的范围,只能进行全量复制。
在这里插入图片描述


实时复制

主从节点在建立复制连接后(此时从节点已经和主节点数据一致了),主节点会把自己收到的修改操作,通过TCP长连接的方式,源源不断的传输给从节点。从节点就会根据这些请求来同时修改自身的数据,从而保持和主节点数据的一致性。

在进行实时复制的时候,需要保证连接处于可以状态;即通过心跳包的方式来维护连接状态(应用层自己实现的心跳)

  • 主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信
  • 主节点默认每隔10秒对从节点发送 ping 命令,判断从节点的存活和连接状态
  • 从节点默认每隔1秒向主节点发送replconf ack offset 命令,给主节点上报自身当前的复制偏移量

如果主节点发现从节点通信延迟超过repl-timeout配置的值,则判断从节点下线,断开复制客户端连接。从节点恢复连接后,心跳机制继续进行


总结

以上就是我的redis学习笔记

在这里插入图片描述


http://www.ppmy.cn/news/1548790.html

相关文章

slf4j 基于 logback 单独打印性能日志到另外一个文件

logback.xml 添加性能日志 <appender name"PERF" class"ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_HOME}/perf.log</file><append>true</append><rollingPolicy class"ch.qos.logback.core.r…

MySQL初学之旅(3)约束

目录 1.前言 2.正文 2.1约束类型 2.2NULL约束 2.3UNIQUE约束 2.4DEFAULT约束 2.5PRIMARY KEY主键约束 2.6FOREIGN KEY外键约束 2.7CHECK约束 3.小结 1.前言 哈喽大家好啊&#xff0c;今儿来继续给大家分享最近学习的MySQL和约束相关的知识点&#xff0c;希望大家一起…

【AIGC】破解ChatGPT!如何使用高价值提示词Prompt提升响应质量

文章目录 为什么高价值提示词如此重要&#xff1f;&#x1f50d;1.1 提升响应的相关性和准确性1.2 节省时间与资源1.3 增强用户体验 了解ChatGPT的工作原理&#x1f9e0;2.1 语言模型的训练过程2.2 上下文理解与生成2.3 限制与挑战 高价值提示词的核心要素✍️3.1 清晰明确的指…

C语言基本知识 2.2void 函数

在C语言中&#xff0c; void 是一个重要的关键字&#xff0c;具有多种用途&#xff0c;以下是详细介绍&#xff1a; 函数返回值类型声明 - 当函数不需要返回任何值时&#xff0c;可以将函数的返回值类型声明为 void 。例如&#xff1a; void printMessage() { printf(…

计算机毕业设计 | SpringBoot+vue汽车资讯网站 汽车购买咨询管理系统(附源码+论文)

1&#xff0c;绪论 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理汽车资讯网站的相关信息成为必然…

ros2 humble 安装 navigation2

安装 Nav2 包&#xff1a; 在安装 ROS 2 的 navigation2 软件包时&#xff0c;你需要将 替换为你安装的 ROS 2 版本的名称&#xff08;如 foxy, galactic, humble 等&#xff09;。因此&#xff0c;正确的命令格式为&#xff1a; sudo apt install ros-<ros2-distro>-n…

03 —— Webpack 自动生成 html 文件

HtmlWebpackPlugin | webpack 中文文档 | webpack中文文档 | webpack中文网 安装 npm install --save-dev html-webpack-plugin 下载html-webpack-plugin本地软件包 npm i html-webpack-plugin --save-dev 配置webpack.config.js让webpack拥有插件功能 const HtmlWebpack…

Tomcat和Nginx原理说明

Tomcat Tomcat 是一个开源的 Java 应用服务器&#xff0c;它由多个关键组件组成。这些组件共同协作&#xff0c;实现了 Servlet 容器的功能。以下是 Tomcat 的核心组件说明及其逻辑架构的示意图。 1. Tomcat 核心组件说明 (1) Server 描述&#xff1a;Tomcat 的顶级组件&…