主从复制概念与原理

核心概念

主节点(Master):唯一接受写操作的节点,数据修改后异步复制到从节点。
从节点(Replica):复制主节点数据的节点,默认只读(可配置为可写但不推荐)。

所以,主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

主要价值

主从复制主要有能实现如下价值:

数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

主从库之间采用的是读写分离的方式,即:
读操作:主库、从库都可以接收;
写操作:首先到主库执行,然后,主库将写操作同步给从库

在这里插入图片描述

复制流程

  1. 从节点连接主节点发送 PSYNC 命令
  2. 主节点执行 BGSAVE 生成 RDB 快照
  3. RDB 文件传输到从节点
  4. 从节点加载 RDB 文件
  5. 主节点将期间的写命令发送到从节点
  6. 持续增量同步
    在这里插入图片描述

关键特性:
异步复制:主节点不等待从节点确认
全量复制:首次连接或复制中断时间过长时触发
部分复制:基于复制偏移量(offset)的增量同步
级联复制:从节点可以作为其他节点的主节点

复制原理

  1. 确立主从关系
    如有 redis01 (172.24.8.11)实例和 redis02 (172.24.8.12),在 redis02 上执行以下这个命令后,redis02 就变成了 redis01 的从库,并从 redis01 上复制数据。
replicaof 172.24.8.11 6379
  1. 全量复制阶段
    在这里插入图片描述

第一阶段:主从库间建立连接、协商同步的过程,主要是为全量复制做准备。在这一步,从库和主库建立起连接,并告诉主库即将进行同步,主库确认回复后,主从库间就可以开始同步了。
具体来说,从库给主库发送 psync 命令,表示要进行数据同步,主库根据这个命令的参数来启动复制。
psync 命令包含了主库的 runID 和复制进度 offset 两个参数。
runID 是每个 Redis 实例启动时都会自动生成的一个随机 ID,用来唯一标记这个实例。
当从库和主库第一次复制时,因为不知道主库的 runID,所以将 runID 设为“?”。
offset,此时设为 -1,表示第一次复制。
主库收到 psync 命令后,会用 FULLRESYNC 响应命令带上两个参数:主库 runID 和主库目前的复制进度 offset,返回给从库。
从库收到响应后,会记录下这两个参数。这里有个地方需要注意,FULLRESYNC 响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库。

第二阶段,主库将所有数据同步给从库。从库收到数据后,在本地完成数据加载。这个过程依赖于内存快照生成的 RDB 文件。
具体来说,主库执行 bgsave 命令,生成 RDB 文件,接着将文件发给从库。从库接收到 RDB 文件后,会先清空当前数据库,然后加载 RDB 文件。
这是因为从库在通过 replicaof 命令开始和主库同步前,可能保存了其他数据。
为了避免之前数据的影响,从库需要先把当前数据库清空。
在主库将数据同步给从库的过程中,主库不会被阻塞,仍然可以正常接收请求。否则,Redis 的服务就被中断了。
但是,这些请求中的写操作并没有记录到刚刚生成的 RDB 文件中。为了保证主从库的数据一致性,主库会在内存中用专门的 replication buffer,记录 RDB 文件生成后收到的所有写操作。

第三个阶段,主库会把第二阶段执行过程中新收到的写命令,再发送给从库。
具体的操作是,当主库完成 RDB 文件发送后,就会把此时 replication buffer 中的修改操作发给从库,从库再重新执行这些操作。这样一来,主从库就实现同步了。

  1. 增量复制

如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大。因此如果出现类似异常之后,主从库会采用增量复制的方式继续同步。

提示:在进行主从复制设置时,强烈建议在主服务器上开启持久化,主要是避免出现如下风险:

假设设置节点A为主服务器,关闭持久化,节点B和C从节点A复制数据。
这时出现了一个崩溃,但Redis具有自动重启系统,重启了进程,因为关闭了持久化,节点重启后只有一个空的数据集。
节点B和C从节点A进行复制,现在节点A是空的,所以节点B和C上的复制数据也会被删除。

读写分离概念与原理

读写分离说明

读写分离是在主从复制基础上实现的,可以实现Redis的读负载均衡:由主节点提供写服务,由一个或多个从节点提供读服务(多个从节点既可以提高数据冗余程度,也可以最大化读负载能力);在读负载较大的应用场景下,可以大大提高Redis服务器的并发量。

读写分离关注点

  • 延迟与不一致问题

由于主从复制的命令传播是异步的,延迟与数据的不一致不可避免。如果应用对数据不一致的接受程度程度较低,可能的优化措施包括:优化主从节点之间的网络环境(如在同机房部署);监控主从节点延迟(通过offset)判断,如果从节点延迟过大,通知应用不再通过该从节点读取数据;使用集群同时扩展写负载和读负载等。

  • 数据过期问题

在单机版Redis中,存在两种删除策略:
+ 惰性删除:服务器不会主动删除数据,只有当客户端查询某个数据时,服务器判断该数据是否过期,如果过期则删除。
+ 定期删除:服务器执行定时任务删除过期数据,但是考虑到内存和CPU的折中(删除会释放内存,但是频繁的删除操作对CPU不友好),该删除的频率和执行时间都受到了限制。
在主从复制场景下,为了主从节点的数据一致性,从节点不会主动删除数据,而是由主节点控制从节点中过期数据的删除。由于主节点的惰性删除和定期删除策略,都不能保证主节点及时对过期数据执行删除操作,因此,当客户端通过Redis从节点读取数据时,很容易读取到已经过期的数据。

提示:在Redis 3.2后,从节点在读取数据时,增加了对数据是否过期的判断:如果该数据已过期,则不返回给客户端。

  • 故障切换问题

在没有使用哨兵的读写分离场景下,应用针对读和写分别连接不同的Redis节点;当主节点或从节点出现问题而发生更改时,需要及时修改应用程序读写Redis数据的连接;连接的切换可以手动进行,或者自己写监控程序进行切换,但前者响应慢、容易出错,后者实现复杂,成本较高。

  • 总结

在使用读写分离之前,可以考虑其他方法增加Redis的读负载能力:如尽量优化主节点(减少慢查询、减少持久化等其他情况带来的阻塞等)提高负载能力;使用Redis集群同时提高读负载能力和写负载能力等。如果使用读写分离,可以使用哨兵,使主从节点的故障切换尽可能自动化,并减少对应用程序的侵入。

参考: Redis进阶 - 高可用:主从复制详解

主从复制架构实践

安全预设

根据实际情况,关闭防火墙和SELinux。

[root@redis01 ~]# systemctl disable firewalld --now
[root@redis01 ~]# sed -i 's/=enforcing/=disabled/g' /etc/selinux/config

注意:以上操作在所有Slave主机上也需要执行。

时钟服务

主从架构建议保证时钟服务正确,具体时钟配置参考:NTP服务器

001.Chrony时间服务器

  • ntpd服务查看
[root@redis01 ~]# ntpq -npremote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*116.62.13.223   100.100.61.92    2 u   28   64  377   34.750   24.098   4.261
+203.107.6.88    100.107.25.114   2 u   13   64  377   47.745   18.287   8.121
  • chrony服务查看
[root@redis01 ~]# chronyc sources -v

Redis 安装

略,参考《001.Redis 简介及安装》。

提示:主从节点都需要安装Redis。

Redis 主节点配置

[root@redis01 ~]# mkdir -p /var/lib/redis/redis01/ /var/log/redis/      #创建Redis RDB持久化文件保存路径[root@redis01 ~]# vim /etc/redis/redis01_6379.conf
#……
# 核心配置项:
bind 0.0.0.0 -::1                       # 允许所有IP连接
protected-mode no                       # 关闭保护模式
port 6379
daemonize yes
logfile /var/log/redis/redis01.log
dir /var/lib/redis/redis01# 主从复制相关
repl-backlog-size 64mb                  # 复制积压缓冲区大小(建议1-2倍内存)
repl-backlog-ttl 3600                   # 缓冲区保留时间(秒)
repl-diskless-sync yes                  # 启用无盘复制(推荐)
repl-diskless-sync-delay 5              # 等待更多从节点加入(秒)
#requirepass "StrongPassword123!" [root@redis01 ~]# systemctl restart redis-server

Redis 从节点配置

[root@redis02 ~]# mkdir -p /var/lib/redis/redis01/ /var/log/redis/      #创建Redis RDB持久化文件保存路径[root@redis02 ~]# vim /etc/redis/redis01_6379.conf
#……
# 核心配置项:
bind 0.0.0.0 -::1                       # 允许所有IP连接
protected-mode no                       # 关闭保护模式
port 6379
daemonize yes
logfile /var/log/redis/redis01.log
dir /var/lib/redis/redis01# 主从复制配置
replicaof 172.24.8.11 6379              # 关键配置:指定主节点
replica-read-only yes                   # 默认,从节点只读(推荐)
repl-diskless-load disabled             # 默认,从节点禁用无盘加载(避免风险)
#masterauth "StrongPassword123!"        # 如果主节点有密码需配置[root@redis02 ~]# systemctl restart redis-server

主从复制验证

  • 状态验证

在主从节点上查看两个节点的状态。

[root@redisclient ~]# redis-cli -h redis01 -p 6379
redis01:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.24.8.12,port=6379,state=online,offset=306,lag=0
master_failover_state:no-failover
master_replid:a8f80c6ab90acb062021f2f0e589191c165022c1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:306
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:67108864
repl_backlog_first_byte_offset:223
repl_backlog_histlen:84
redis01:6379> exit[root@redisclient ~]# redis-cli -h redis02 -p 6379
redis02:6379> INFO replication
# Replication
role:slave
master_host:172.24.8.11
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_read_repl_offset:320
slave_repl_offset:320
replica_full_sync_buffer_size:0
replica_full_sync_buffer_peak:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a8f80c6ab90acb062021f2f0e589191c165022c1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:320
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:237
repl_backlog_histlen:84
  • 数据验证
[root@redisclient ~]# redis-cli -h redis01 -p 6379
redis01:6379> SET master_key "value_from_master"
OK
redis01:6379> exit[root@redisclient ~]# redis-cli -h redis02 -p 6379
redis02:6379> GET master_key
"value_from_master"
redis02:6379> exit

模拟宕机

在这里插入图片描述

  • 停止主节点
[root@redis01 ~]# systemctl stop redis-server
  • 2从节点查看状态
[root@redisclient ~]# redis-cli -h redis02 -p 6379
redis02:6379> INFO replication
master_link_status:down                     # 显示连接断开
  • 提升从节点为主节点(临时方案)
[root@redisclient ~]# redis-cli -h redis02 -p 6379
redis02:6379> REPLICAOF NO ONE  # 取消复制关系

节点切换后,对应的应用程序也需要修改数据库IP。

提示;主从复制本身不提供自动故障切换,需要手动执行切换,然后程序需要手动重新指定IP。

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

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

相关文章

Android Studio 模拟器 “******“ has terminated 问题

问题:Android Studio 模拟器 "**" has terminated 问题设备信息:CPU:I5 7500U RAM:64GB System:Windows 10 64位解决: 网上所有办法都尝试后仍然不可行可尝试如下办法:1、此电脑→管理→设备管理→显示适配器→右击→…

uniapp 懒加载图片

实现的功能 1.一次性获取图片。 2.按用户视野范围内看到的图片滚动下来进行懒加载,提高浏览器性能。 3.不要一次性加载全部的图片 1.给父组件绑定一个滚动监听 1.页面路径:/pages/Home/index.vue 不在一个页面的话用 EventBus去触发。@scroll="handleScroll2" Ev…

Android - 资源类型 MINE Type

一、概念MINE(Multipurpose Internet Mail Extensions)最初是为了标识电子邮件附件的类型,在 HTML 中使用 content-type 属性表示,描述了文件类型的互联网标准。格式:媒体类型/子类型,可使用通配符*。如 au…

php8.+ 新函数总结

PHP系统函数是PHP核心提供的内置函数,用于执行常见任务,如字符串操作、数组处理、数学运算等。它们通过预定义代码块封装了特定功能,开发者可直接调用而无需重复编写代码。 而 PHP 8.0以后又新增了一些实用函数,今天总结部分常见的…

Qt事件处理机制详解

一、事件处理基本流程在Qt中,所有从QObject派生的类都能处理事件。事件处理的核心流程如下:事件入口函数:bool QObject::event(QEvent *e)参数e包含事件信息,通过e->type()获取事件类型返回值true表示事件已被处理,…

Zynq中级开发七项必修课-第三课:S_AXI_GP0 主动访问 PS 地址空间

Zynq中级开发七项必修课-第三课:S_AXI_GP0 主动访问 PS 地址空间 目标1.0 编写 AXI-Lite Master:按键计数 → 写入 PS 内存1.1 PL 触发中断 → PS 响应并串口打印按键计数值BD图axi_lite_master.v // // AXI4-Lite Simple Master (single-shot, non-pip…

CVPR | 2025 | MAP:通过掩码自回归预训练释放混合 Mamba - Transformer 视觉骨干网络的潜力

文章目录CVPR | 2025 | MAP:通过掩码自回归预训练释放混合 Mamba - Transformer 视觉骨干网络的潜力创新点初步研究初步结论方法确定一个混合网络方法掩码机制掩码比例MAP的transformer解码器重建目标实验ImageNet-1k 上的 2D 分类CVPR | 2025 | MAP:通过…

Spring Boot + Spring AI 最小可运行 Demo

一. 项目依赖&#xff08;pom.xml&#xff09;<project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/mav…

AI重塑校园教育:中小学AI智慧课堂定制方案+AI作业批改减负,告别一刀切学生进步快

家长们&#xff0c;你有没有听过孩子抱怨上学的烦恼&#xff1f;课堂上老师讲的内容&#xff0c;有的同学觉得太简单 “吃不饱”&#xff0c;有的却跟不上 “听不懂”&#xff1b;放学后作业堆成山&#xff0c;老师要熬夜批改到半夜&#xff0c;错题反馈要等第二天才能拿到&…

旧物循环,交易新生——旧物回收二手交易小程序,引领绿色消费新风尚

在资源日益紧张、环境污染问题日益突出的今天&#xff0c;绿色消费已经成为时代发展的必然趋势。旧物回收二手交易小程序&#xff0c;作为绿色消费的重要载体&#xff0c;正以其独特的优势和魅力&#xff0c;引领着一场关于旧物循环、交易新生的绿色革命。一、旧物循环&#xf…

刷机维修进阶教程-----如何清除云账号 修复wifi 指南针 相机 指纹等刷机故障

在刷机、系统升级或降级过程中,是否遇到过以下问题:WiFi无法开启、相机无响应、指南针或陀螺仪失灵 指纹等故障?另外,云账号是否仍会保留,即使通过9008模式刷机也无法彻底清除?那么这篇博文都可以找到答案。 通过博文了解💝💝💝 1💝💝💝----云账号信息分区如…

AI翻唱实战:用[灵龙AI API]玩转AI翻唱 – 第6篇

历史文章 [灵龙AI API] 申请访问令牌 - 第1篇 [灵龙AI API] AI生成视频API&#xff1a;文生视频 – 第2篇 图生视频实战&#xff1a;用[灵龙AI API]玩转AI生成视频 – 第2篇&#xff0c;从静图到大片 单图特效实战&#xff1a;用[灵龙AI API]玩转AI生成视频 – 第3篇&#…

大模型0基础开发入门与实践:第11章 进阶:LangChain与外部工具调用

第11章 进阶&#xff1a;LangChain与外部工具调用 1. 引言 在上一章&#xff0c;我们成功地创造了我们的第一个“生命”——一个可以对话的机器人。我们为它的诞生而兴奋&#xff0c;但很快我们就会发现它的局限性。它就像一个被囚禁在玻璃房中的天才大脑&#xff0c;拥有渊博…

SQL 日期处理:深入解析与高效实践

SQL 日期处理&#xff1a;深入解析与高效实践 引言 在数据库管理中&#xff0c;日期和时间数据的处理是不可或缺的一部分。SQL&#xff08;结构化查询语言&#xff09;提供了丰富的日期和时间函数&#xff0c;使得对日期的处理变得既灵活又高效。本文将深入探讨SQL日期处理的相…

源代码部署 LAMP 架构

源代码部署 LAMP 架构 &#xff08;Linux Apache MySQL PHP&#xff09; 一、LAMP 架构概述 LAMP 是一套经典的开源 Web 服务架构&#xff0c;通过源代码安装可实现高度定制化&#xff0c;适用于对软件版本、功能模块有特定需求的场景。本指南基于 CentOS 7 系统&#xf…

GO环境变量中GO111MODULE到底是干啥的?

查看GO111MODULE变量GO111MODULE的作用GO111MODULE的案例演示 一&#xff0c;查看GO111MODULE变量 ]# go env GO111MODULE 或者 ]# go env | grep GO111MODULE二&#xff0c;GO111MODULE的作用 auto : 自动判断机制 当项目位于 $GOPATH/src 目录外且包含 go.mod 文件时&…

在线培训机构如何降低培训视频被盗录的风险

每一节精心录制的培训视频&#xff0c;都凝聚着讲师的心血与机构的巨大投入。然而&#xff0c;只需一个简单的录屏软件&#xff0c;这一切都可能被轻易窃取。一旦被盗取&#xff0c;不但会损失经济利益&#xff0c;还可能会影响机构的声誉。那么&#xff0c;在线培训机构如何降…

Docker:安装配置

目录一、卸载旧版本二、配置Docker的yum库三、安装Docker3.1 在线安装方式3.2 离线安装方式四、配置阿里云镜像加速【选配】五、Docker服务相关命令六、导出和导入镜像官网 一、卸载旧版本 首先如果系统中已经存在旧版本的Docker&#xff0c;则先卸载&#xff1a; yum remov…

RabbitMQ:SpringAMQP 入门案例

目录一、概述二、基础配置三、生产者四、消费者一、概述 这是一篇Java集成RabbitMQ的入门案例&#xff0c;在这里我们做一个小案例&#xff0c;来体会一下RabbitMQ的魅力。 首先我们要做的就是创建一个生产者一个消费者&#xff1a; 生产者直接向RabbitMQ的队列&#xff08;Q…

Ubuntu 下面安装搜狗输入法debug记录

目录0. 整体安装流程1. 在键盘输入法系统中&#xff0c;没有“fcitx”选项解决方法0. 整体安装流程 详细的Ubuntu搜狗输入法安装指南请参考官方教程&#xff1a;Ubuntu搜狗输入法安装指南 1. 在键盘输入法系统中&#xff0c;没有“fcitx”选项 即使是安装完 fcitx&#xff0…