【Redis分布式】主从复制

news2025/7/14 3:37:55

     🔥个人主页: 中草药

🔥专栏:【中间件】企业级中间件剖析


 一、主从复制

        在分布式系统之中为了解决单点问题(1、可用性问题,该机器挂掉服务会停止2、性能支持的并发量是有限的)通常会把数据复制多个副本部署在其他服务器,满足故障和负载均衡的要求。

        Redis 主从复制(Master-Slave Replication)是一种数据同步机制,允许将一台 Redis 服务器(主节点,Master)的数据复制到其他 Redis 服务器(从节点,Slave)。主从复制在 Redis 中广泛用于数据冗余、读写分离、故障恢复和高可用性架构。

 在实际业务场景之中,读操作往往比写操作更加频繁,主从模式,主要是针对“读操作”进行 并发量&可用性的提高


核心概念

主节点(Master)

  • 负责处理客户端的写操作(SETDEL 等)。

  • 数据变更后,主节点将写命令异步发送给从节点。

  • 每个 Redis 实例默认都是主节点。

从节点(Slave)

  • 复制主节点的数据,默认只处理读操作(GET 等)。

  • 可以配置为级联复制(从节点作为其他从节点的主节点)。

  • 一个主节点可以有多个从节点。

可读

        默认情况下,从节点使用 slave-read-only=yes 配置为只读模式。即使修改此处为no,允许从节点进行写操作修改,由于复制只能从主节点到从节点,对于从节点的任何修改主节点都无法感知,修改从节点会造成主从数据不一致。所以建议线上不要修改从节点的只读模式。

传输延迟

        主从节点一般部署在不同机器上,复制时的网络延迟就成为需要考虑的问题,Redis为我们提供了 repl-disable-tcp-nodelay 参数用于控制是否关闭 TCP_NODELAY(TCP内部的nagle算法),默认为 no,即开启 tcp-nodelay功能,说明如下:
        当关闭时,主节点产生的命令数据无论大小都会及时地发送给从节点,这样主从之间延迟会变小,但增加了网络带宽的消耗。适用于主从之间的网络环境良好的场景,如同机房部署。
        当开启时,主节点会合并较小的TCP 数据包从而节省带宽。默认发送时间间隔取决于Linux的内核,一般默认为 40 毫秒。这种配置节省了带宽但增大主从之间的延迟。适用于主从网络环境复杂的场景,如跨机房部署。

拓扑结构

一主一从

最简单的模式,用于数据备份和读写分离。

一主多从

主节点处理写操作,多个从节点分担读负载。

树状结构(级联复制)

从节点可以作为其他从节点的主节点,降低主节点压力。

例如:Master -> Slave1 -> Slave2

Slave1仍然是从节点,无法进行写操作,只是作为了slave2节点同步数据的来源

此结构主节点无需 一主多从 结构那么高的网卡带宽,但是一旦数据进行修改,同步的传输延时比其要更长


配置主从复制

1. 静态配置(redis.conf)

在从节点的配置文件中添加:

slaveof <master-ip> <master-port>  # 指定主节点地址
masterauth <password>              # 如果主节点有密码

注意:daemonsize要设置为 yes(允许后台运行) 

2. 动态配置(运行时命令)

通过 Redis 命令动态设置主从关系:

# 在从节点上执行:
SLAVEOF 192.168.1.100 6379  # 将该节点设置为某个主节点的从节点
SLAVEOF NO ONE               # 停止复制,恢复为主节点

示例:一主一从

# 主节点(端口 6379)
redis-server --port 6379

# 从节点(端口 6380)
redis-server --port 6380 --slaveof 127.0.0.1 6379

配置成功后

注意:

如果使用 service redis-server start 启动的 redis 则同样要使用 service redis-server stop 来终止redis ,使用kill -9 会自动重启 


 基本流程

配置从节点:在从节点(slave 6380)上通过 slaveof 127.0.0.1 6379 命令配置主节点(master 6379)的 IP 和端口 ,让从节点知道主节点位置。

保存主节点信息:从节点接收配置命令后,保存主节点的地址信息,如 IP、端口等,为后续连接做准备。

主从建立连接:从节点根据保存的主节点信息,主动与主节点建立网络连接-TCP,搭建起主从通信链路。(TCP的三次握手是为了通信双方能正常读写数据)

发送 ping 命令:连接建立后,从节点向主节点发送 ping 命令,用于检测主节点是否可达,以及检查网络连接状态是否正常 。

权限验证:若主节点设置了访问密码,从节点需进行权限验证,提供正确密码才能继续后续操作,保证数据安全。

以上都为准备操作,下面为主从复制的主要操作

同步数据集:验证通过后,从节点向主节点发送同步请求,主节点执行 bgsave 命令生成 RDB 文件并发送给从节点,从节点接收并加载 RDB 文件,将数据恢复到自身,实现数据的初次同步 。

命令持续复制:初次同步完成后,主节点会将后续接收到的写命令持续发送给从节点,从节点执行这些命令,保证主从节点数据的实时一致性。


数据同步psync

redis提供了psync命令,去完成数据同步的过程,此命令不需要我们手动执行,再建立好主从关系之后,会自动执行

PSYNC replicationid offset

 

  1. 从节点发送 psync 命令给主节点,replid 和 offset 的默认值分别是?和 -1.
  2. 主节点根据 psync 参数和自身数据情况决定响应结果:
  • 如果回复 +FULLRESYNC replid offset,则从节点需要进行全量复制流程。
  • 如果回复 +CONTINUE,从节点进行部分复制流程。
  • 如果回复 -ERR,说明 Redis 主节点版本过低,不支持 psync 命令。从节点可以使用 sync 命令进行全量复制。
  • psync 一般不需要手动执行. Redis 会在主从复制模式下自动调用执行.
  • sync 会阻塞 redis server 处理其他请求. psync 则不会.

查看主从结构信息

info replication

 

断开主从结构

断开与主节点的复制关系,不会丢弃原有数据,只是无法再从主节点上获取到数据变化

此处的修改是临时性的,如果重新启动该服务,仍然会按照最初在配置文件设置的内容来建立主从关系

replicationid

也叫 replid ,是用于标识主节点身份的唯一标识符 ,是主节点自动生成的(从节点升级为主节点也会生成,且主节点每次重启生成的replicationid都是不同的)。描述数据的来源

其中,replicationid2 一般是用不到,可以用于因网络波动的原因导致从节点升级为主节点生成的replicationid会取代原先的位置,而此时replicationid2会记录之前的replicationid,后续可以据此重新建立主从关系--哨兵机制会自动完成这个过程

offset

即复制偏移量 ,以字节为单位。

主节点每处理一个写命令,就将命令的字节长度累加到 master_repl_offset ,它表示主节点已向从节点发送了多少字节的数据,体现主节点的写入进度

从节点接收并执行主节点传来的写命令后,也会累加更新 slave_repl_offset ,代表从节点的复制进度

这两个参数共同描述了一个数据集,当这两个数据相同,表示数据状态是一致的,并且同步状态良好


主从复制分为两个阶段:全量复制(初次同步)和 增量复制(持续同步)。

全量复制(Full Resynchronization)

当从节点首次连接主节点或复制关系中断后需要重新同步时触发:

1) 从节点发送 psync 命令给主节点进行数据同步,由于是第一次进行复制,从节点没有主节点的运行 ID 和复制偏移量,所以发送 psync ? -1。

2) 主节点根据命令,解析出要进行全量复制,回复 +FULLRESYNC 响应。

3) 从节点接收主节点的运行信息进行保存。

4) 主节点执行 bgsave 进行 RDB 文件的持久化。(防止传输的RDB文件为旧文件)

5) 主节点发送 RDB 文件给从节点,从节点保存 RDB 数据到本地硬盘。

6) 主节点将从生成 RDB 到接收完成期间执行的写命令,写入缓冲区中,等从节点保存完 RDB 文件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照 rdb 的二进制格式追加写入到收到的 rdb 文件中.保持主从一致性。

7) 从节点清空自身原有旧数据。

8) 从节点加载 RDB 文件得到与主节点一致的数据。

9) 如果从节点加载 RDB 完成之后,并且开启了 AOF 持久化功能,它会进行 bgrewrite 操作,得到最近的 AOF 文件。

全量复制的无磁盘复制 (diskless)

        默认情况下,进行全量复制需要主节点生成 RDB 文件到主节点的磁盘中,再把磁盘上的 RDB 文件通过发送给从节点。

        Redis 从 2.8.18 版本开始支持无磁盘复制。主节点在执行 RDB 生成流程时,不会生成 RDB 文件到磁盘中了,而是直接把生成的 RDB 数据通过网络发送给从节点。这样就节省了一系列的写硬盘和读硬盘的操作开销(但实际上,由于全量复制需要大规模数据的网络传输,因此整个操作还是比较重的)。

注意 部分资料会把 runId 和replicationid混淆,但是通过源码阅读可知,run id 是一个随机生成的,他的主要作用是支持哨兵机制的,并不在主从复制功能起到一定作用

部分复制(Partial Resynchronization)

1)当主从节点之间出现网络中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并终端复制连接。

2)主从连接中断期间主节点依然响应命令,但这些复制命令都因网络中断无法及时发送给从节点,所以暂时将这些命令滞留在repl-backing-buffer(是内存中一个基于数组构成的环形队列,会记录一段时间修改的数据,随着时间的推移会删除之前的旧数据)复制积压缓冲区中。

3)当主从节点网络恢复后,从节点再次连上主节点。

4)从节点将之前保存的 replicationId 和 复制偏移量作为 psync 的参数发送给主节点,请求进行部分复制。

5)主节点接到 psync 请求后,进行必要的验证。随后根据 offset 去复制积压缓冲区查找合适的数据,并响应 +CONTINUE 给从节点。

6)主节点将需要从节点同步的数据发送给从节点,最终完成一致性。 

实时复制

全量复制完成后,主节点持续将新的写命令发送给从节点:

实时同步

主节点每执行一个写命令,就异步将该命令发送给所有从节点。从节点接收并执行这些命令,保持数据同步。

在进行实时复制的时候,需要保证连接处于可用状态

心跳包机制
主节点:默认,每隔 10s 给从节点发送一个 ping 命令。从节点收到就返回 pong
从节点:默认,每隔 1s 就给主节点发起一个特定的请求,就会上报当前从节点复制数据的进度 (offset)


关键配置参数

参数说明
repl-backlog-size复制积压缓冲区大小(影响断线后增量复制能力)
repl-timeout复制超时时间(默认 60 秒)
min-slaves-to-write主节点至少需要 N 个从节点连接才允许写操作
min-slaves-max-lag从节点最大延迟时间(秒)

局限性

异步复制

主从节点数据同步是异步的,从节点数据可能短暂落后(最终一致性)。且当从节点数量增多,复制数据的延时会非常明显

主节点单点故障

主节点宕机后,从节点不能自动升级,需手动切换从节点为主节点,非常繁琐(需配合 Sentinel 或 Cluster 实现自动故障转移)。

Redis的哨兵机制--自动对挂了的主节点进行替换


补充

主从节点断开连接的情况有两种

1)主动修改redis的组成结构,通过slave no one,这种情况 从节点会自动升级为主节点

2)主节点挂掉后,需要通过人工干预


欲变世界,先变其身。        ——圣雄甘地

🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐

  制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸 

 

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

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

相关文章

用递归实现各种排列

为了满足字典序的输出&#xff0c;我采用了逐位递归的方法&#xff08;每一位的所能取到的最小值都大于前一位&#xff09; 1&#xff0c;指数型排列 #include<bits/stdc.h> using ll long long int; using namespace std; int a[10];void printp(int m) {for (int h …

测试用例介绍

文章目录 一、测试用例基本概念1.1 测试用例基本要素 二、测试用例的设计方法2.1 基于需求的设计方法2.2 等价类2.3 边界值2.4 错误猜测法2.6 场景设计法2.7 因果图2.5 正交排列 三、综合&#xff1a;根据某个场景去设计测试用例&#xff08;万能公式&#xff09;四、如何使用F…

phpstudy升级新版apache

1.首先下载要升级到的apache版本&#xff0c;这里apache版本为Apache 2.4.63-250207 Win64下载地址&#xff1a;Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压&#xff0c; 将Apache24复制一份到ph…

React Native基础环境配置

React Native基础环境配置 1.引言2.React-Native简介3.项目基础环境搭建1.引言 感觉自己掌握的知识面还是有点太窄了,于是决定看看移动端的框架,搞个react搭一个后端管理项目,然后拿react-native写个小的软件,试着找个三方上架一下应用市场玩玩。毕竟不可能一直在简历上挂一…

【Linux修炼手册】Linux开发工具的使用(一):yum与vim

文章目录 一、Linux 软件包管理器——yum安装与卸载的使用方法查看软件包 二、Linux编辑器——vimvim命名模式常用指令底行模式常用指令 一、Linux 软件包管理器——yum Linux安装软件的方式有3种&#xff1a; 源代码安装——成本极高rmp安装——具有安装依赖、安装源、安装版…

如何查看电脑显卡配置参数 一文读懂

显卡是电脑的重要硬件之一&#xff0c;尤其对于游戏玩家、设计师、视频编辑等用户来说&#xff0c;显卡的性能直接影响电脑的使用体验。如果您想知道电脑的显卡信息&#xff0c;或者打算升级显卡&#xff0c;那么了解如何查看显卡配置是非常必要的。本文将为您提供多种简单实用…

spring中的@ComponentScan注解详解

ComponentScan 是 Spring 框架中用于自动扫描并注册组件的核心注解&#xff0c;它简化了 Spring 应用中 Bean 的发现和装配流程。以下从核心功能、属性解析、使用场景及示例等方面进行详细说明。 一、核心功能与作用 自动扫描组件 ComponentScan 会扫描指定包及其子包下的类&am…

深入剖析 I/O 复用之 select 机制

深入剖析 I/O 复用之 select 机制 在网络编程中&#xff0c;I/O 复用是一项关键技术&#xff0c;它允许程序同时监控多个文件描述符的状态变化&#xff0c;从而高效地处理多个 I/O 操作。select 作为 I/O 复用的经典实现方式&#xff0c;在众多网络应用中扮演着重要角色。本文…

SpringBoot指定项目层日志记录

1、新建一个Springboot项目&#xff0c;添加Lombok依赖&#xff08;注意&#xff1a;这里使用的Lombok下的Slf4j快速日志记录方式&#xff09; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependenc…

RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE

RV BACKTRACE 简介 本文主要讲述RV BACKTRACE 的内部主要原理 没有接触过rvbacktrace可以看下面两篇文章&#xff0c;理解一下如何使用RVBACKTRACE RVBacktrace RISC-V极简栈回溯组件&#xff1a;https://club.rt-thread.org/ask/article/64bfe06feb7b3e29.html RVBacktra…

matlab 中function的用法

matlab 中function的用法 前言介绍1. 基本语法示例&#xff08;1&#xff09;可以直接输出&#xff08;2&#xff09;调用函数 2.输入参数和输出参数示例多输入参数和输出参数定义一个函数&#xff0c;计算两个数的和与差&#xff1a;调用该函数&#xff1a; 3. 默认参数示例 4…

解锁 LLM 推理速度:深入 FlashAttention 与 PagedAttention 的原理与实践

写在前面 大型语言模型 (LLM) 已经渗透到我们数字生活的方方面面,从智能问答、内容创作到代码辅助,其能力令人惊叹。然而,驱动这些强大模型的背后,是对计算资源(尤其是 GPU)的巨大需求。在模型推理 (Inference) 阶段,即模型实际对外提供服务的阶段,速度 (Latency) 和吞…

4个纯CSS自定义的简单而优雅的滚动条样式

今天发现 uni-app 项目的滚动条不显示&#xff0c;查了下原来是设置了 ::-webkit-scrollbar {display: none; } 那么怎么用 css 设置滚动条样式呢&#xff1f; 定义滚动条整体样式‌ ::-webkit-scrollbar 定义滚动条滑块样式 ::-webkit-scrollbar-thumb 定义滚动条轨道样式‌…

查看jdk是否安装并且配置成功?(Android studio安装前的准备)

WinR输入cmd打开命令提示窗口 输入命令 java -version 回车显示如下&#xff1a;

5月8日直播见!Atlassian Team‘25大会精华+AI实战分享

在刚刚落幕的 Atlassian Team’25 全球大会上&#xff0c;Atlassian发布了多项重磅创新&#xff0c;全面升级其协作平台&#xff0c;涵盖从Al驱动、知识管理到跨团队协作&#xff0c;再到战略执行的各个方面。 为帮助中国用户深入了解这些前沿动态&#xff0c;Atlassian全球白…

Windows系统下使用Kafka和Zookeeper,Python运行kafka(一)

下载和安装见Linux系统下使用Kafka和Zookeeper 配置 Zookeeper Zookeeper 是 Kafka 所依赖的分布式协调服务。在 Kafka 解压目录下,有一个 Zookeeper 的配置文件模板config/zookeeper.properties,你可以直接使用默认配置。 启动 Zookeeper 打开命令提示符(CMD),进入 K…

C++之“继承”

继续开始关于C相关的内容。C作为面向对象的语言&#xff0c;有三大特性&#xff1a;封装&#xff0c;继承&#xff0c;多态。 这篇文章我们开始学习&#xff1a;继承。 一、继承的概念和定义 1. 继承的概念 什么是继承呢&#xff1f; 字面意思理解来看&#xff1a;继承就是…

Webug4.0靶场通关笔记19- 第24关邮箱轰炸

目录 第24关 邮箱轰炸 1.配置环境 2.打开靶场 3.源码分析 4.邮箱轰炸 &#xff08;1&#xff09;注册界面bp抓包 &#xff08;2&#xff09;发送到intruder &#xff08;3&#xff09;配置position &#xff08;4&#xff09;配置payload &#xff08;5&#xff09;开…

java CompletableFuture 异步编程工具用法1

1、测试异步调用&#xff1a; static void testCompletableFuture1() throws ExecutionException, InterruptedException {// 1、无返回值的异步任务。异步线程执行RunnableCompletableFuture.runAsync(() -> System.out.println("only you"));// 2、有返回值的异…

若依框架Ruoyi-vue整合图表Echarts中国地图标注动态数据

若依框架Ruoyi-vue整合图表Echarts中国地图 概述创作灵感预期效果整合教程前期准备整合若依框架1、引入china.json2、方法3、data演示数据4、核心代码 完整代码[毫无保留]组件调用 总结 概述 首先&#xff0c;我需要回忆之前给出的回答&#xff0c;确保这次的内容不重复&#…