Redis主从复制:告别单身Redis!

在这里插入图片描述

目录

    • 一、 为什么需要主从复制?🤔
    • 二、 如何搭建主从架构?
      • 前提条件✅
      • 步骤
        • 📁 创建工作目录
        • 📜 创建 Docker Compose 配置文件
        • 🚀 启动所有 Redis
        • 🔍 验证主从状态
      • 💡 重要提示和后续改进
    • 三、 主从复制的数据同步原理是什么?
    • 四、 主从复制的优缺点是什么?
    • 五、 总结

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

🌟了解 缓存雪崩、穿透、击穿 请看 : 缓存雪崩、穿透、击穿:别让你的数据库“压力山大”!

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning


Redis主从复制,可以把它想象成一个“跟班”系统

  • Master (主节点):就是“大哥” ,所有的事情(写数据📝、改数据✏️)都由他说了算,他手里有最新的、最全的信息(数据)。
  • Slave (从节点):就是“小弟”或“跟班” ,他们不直接干活(默认不能写数据),主要任务就是时刻盯着大哥 👀,大哥做了什么,他们就跟着学(复制数据🔄),保持和大哥信息同步。
    在这里插入图片描述

一、 为什么需要主从复制?🤔

主要有这么几个原因:

  • a. 数据备份与高可用 (大哥万一出事了 💀,有人顶上 💪)

    • 备份:小弟手里有大哥数据的完整副本 📑。万一大哥突然“挂了”(服务器宕机、硬盘坏了),数据不会完全丢失,至少小弟那里还有一份。
    • 高可用:如果大哥真的出事了,我们可以快速“提拔”一个小弟当新大哥(这个过程叫“故障转移”,通常需要配合哨兵模式或集群模式自动完成 ✨),保证服务能快速恢复,不会停太久。
  • b. 读写分离,提升性能 (大哥太忙 🥵,小弟分担点任务 🤝)

    • 在一个系统中,“读”数据的操作往往比“写”数据的操作多得多。
    • 如果所有读写请求都压在大哥一个人身上,他可能会累垮(性能瓶颈 🏺)。
    • 有了小弟后,可以让大哥专门处理“写”请求和少量的“读”请求,而把大量的“读”请求分流给各个小弟去处理。这样大家分工合作,整个系统的处理能力就上去了 🚀,响应速度也更快 ⚡。这就像大哥负责决策和发布命令,小弟们负责对外宣传和解答疑问。
  • c. 负载均衡 (分摊压力 ⚖️)

    • 和读写分离类似,多个小弟可以分摊读请求的压力,避免所有读请求都集中在一台服务器上。

二、 如何搭建主从架构?

下面是使用一台 Linux 服务器和 Docker 技术搭建 Redis 一主二从(Master-Slave)复制结构的步骤。我们将使用 Docker Compose 来简化管理。

前提条件✅

  1. 拥有一台 Linux 服务器 🖥️。
  2. 服务器上已安装 Docker 和 Docker Compose 🐳(这里就不演示了,自行查找教程安装)。
  3. 安装完成之后,使用 docker pull redis 来拉去最新的redis的镜像。

步骤

📁 创建工作目录

在你的服务器上选择一个合适的位置,创建一个用于存放配置文件的目录。

 mkdir redis-clustercd redis-cluster
📜 创建 Docker Compose 配置文件

redis-cluster 目录下创建一个名为 docker-compose.yml 的文件,并填入以下内容:

services:redis-master:image: redis:latest # 或者指定具体版本, 如 redis:7.2container_name: redis-masterports:- "6379:6379" # 将主节点的 6379 端口映射到宿主机的 6379 端口networks:- redis-net# 可以添加 volumes 实现数据持久化 (可选) 💾# volumes:#   - ./master-data:/data#   - ./master-redis.conf:/usr/local/etc/redis/redis.conf # 如果需要自定义配置# command: redis-server /usr/local/etc/redis/redis.conf # 如果使用了自定义配置redis-slave1:image: redis:latestcontainer_name: redis-slave1ports:- "6380:6379" # 将第一个从节点的 6379 端口映射到宿主机的 6380 端口networks:- redis-netcommand: redis-server --slaveof redis-master 6379 # 🔑 指定主节点地址和端口depends_on:- redis-master # 确保主节点先启动# 可以添加 volumes 实现数据持久化 (可选) 💾# volumes:#   - ./slave1-data:/data#   - ./slave1-redis.conf:/usr/local/etc/redis/redis.conf# command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379redis-slave2:image: redis:latestcontainer_name: redis-slave2ports:- "6381:6379" # 将第二个从节点的 6379 端口映射到宿主机的 6381 端口networks:- redis-netcommand: redis-server --slaveof redis-master 6379 # 🔑 指定主节点地址和端口depends_on:- redis-master # 确保主节点先启动# 可以添加 volumes 实现数据持久化 (可选) 💾# volumes:#   - ./slave2-data:/data#   - ./slave2-redis.conf:/usr/local/etc/redis/redis.conf# command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379networks:redis-net:driver: bridge # 创建一个桥接网络供容器间通信

配置说明:

  • services: 定义了三个服务(容器):redis-master, redis-slave1, redis-slave2
  • image: redis:latest: 指定使用最新的官方 Redis 镜像。建议在生产环境中使用具体的版本号(如 redis:7.2)。
  • container_name: 为容器指定一个易于识别的名称。
  • ports: 将容器的 6379 端口映射到宿主机的不同端口。redis-master 映射到 6379,redis-slave1 映射到 6380,redis-slave2 映射到 6381。这样你可以在宿主机上通过不同端口访问它们。
  • networks: - redis-net: 将所有容器连接到名为 redis-net 的自定义 Docker 网络。这使得容器可以通过容器名称(redis-master, redis-slave1, redis-slave2)相互通信。
  • command: redis-server --slaveof redis-master 6379 🔑: 这是关键配置。它告诉 redis-slave1redis-slave2 容器启动时,连接到名为 redis-master 的容器的 6379 端口,并成为它的从节点。
  • depends_on: - redis-master: 确保从节点容器在主节点容器启动之后再启动。
  • networks: redis-net: driver: bridge: 定义了一个名为 redis-net 的自定义桥接网络。
  • volumes (注释掉的部分) 💾: 如果需要数据持久化(即使容器停止或删除,数据也不会丢失),取消这些行的注释。
    • ./master-data:/data:将宿主机当前目录下的 master-data 文件夹挂载到 redis-master 容器内的 /data 目录(Redis 默认数据存储目录)。你需要手动创建 master-data, slave1-data, slave2-data 目录。
    • ./master-redis.conf:/usr/local/etc/redis/redis.conf:如果你需要更复杂的 Redis 配置(如设置密码 requirepassmasterauth,修改 RDB/AOF 配置等),可以创建一个 redis.conf 文件,并将其挂载到容器内。如果挂载了自定义配置文件,通常需要修改 command 来指定加载该配置文件。
🚀 启动所有 Redis

redis-cluster 目录下(包含 docker-compose.yml 文件的目录),运行以下命令:

# 启动容器并在后台运行
docker compose up -d
# 如果你的 docker compose 不是插件形式,可能是 docker-compose up -d

在这里插入图片描述

Docker Compose 会根据 `docker-compose.yml` 文件创建并启动三个 Redis 容器。`-d` 参数表示在后台(detached mode)运行。
🔍 验证主从状态
  • 查看容器状态:

    docker compose ps
    # 或者 docker ps
    

    在这里插入图片描述

    你应该能看到 redis-master, redis-slave1, redis-slave2 三个容器正在运行 (State 为 Up)。✅

  • 检查主节点信息:
    连接到主节点容器并查看复制信息。

    docker exec -it redis-master redis-cli
    

    进入 redis-cli 后,输入:

    INFO replication
    

    在这里插入图片描述

    在输出中查找:

    • role:master ✅:确认它是主节点。
    • connected_slaves:2 ✅:确认有两个从节点连接。
    • 下面会列出两个 slave 的信息(IP、端口、状态等)。
  • 检查从节点信息:
    连接到任意一个从节点容器(例如 redis-slave1)并查看复制信息。

    docker exec -it redis-slave1 redis-cli
    

    进入 redis-cli 后,输入:

    INFO replication
    

    在这里插入图片描述

    在输出中查找:

    • role:slave ✅:确认它是从节点。
    • master_host:redis-master ✅:确认主节点的主机名正确。
    • master_port:6379 ✅:确认主节点的端口正确。
    • master_link_status:up ✅:确认与主节点的连接正常。
  • ➡️ 测试数据同步:

    1. 主节点 (redis-master) 的 redis-cli 中设置一个键值对:
      SET mykey "hello world from master! 👋"
      
      应该返回 OK
    2. 从节点 (redis-slave1redis-slave2) 的 redis-cli 中获取这个键的值:
      GET mykey
      
      应该能成功返回 "hello world from master! 👋"。这表明数据已从主节点同步到从节点 🎉。
      在这里插入图片描述

🛑 停止和清理 (如果需要):
如果你想停止并删除这些容器、网络,可以在 redis-cluster 目录下运行:

docker compose down

如果使用了挂载卷(volumes)并且想删除数据,可以添加 -v 选项:

docker compose down -v # 这个会把数据也删掉哦,请小心!

💡 重要提示和后续改进

  • 数据持久化: 上面的示例默认没有启用持久化。对于生产环境,强烈建议通过挂载 volumes 💾 来持久化 /data 目录,并可能需要配置 RDB 快照或 AOF 日志。
  • 安全性: 示例没有设置密码 🔑。在生产环境中,务必为主节点设置 requirepass,并为从节点设置 masterauth 来连接到需要密码的主节点。这需要在自定义的 redis.conf 文件中配置,并通过 volumes 挂载进去,同时修改 command 以加载配置文件。
  • 高可用: 这个设置只是主从复制,如果主节点宕机 💥,从节点不会自动提升为主节点。你需要手动处理故障转移,或者使用 Redis Sentinel(哨兵模式)或 Redis Cluster(集群模式)来实现自动故障转移和更高可用性。
  • 资源限制: 在生产环境中,你可能需要为每个 Redis 容器设置 CPU 和内存限制 ⚖️,以防止它们消耗过多服务器资源。这可以在 docker-compose.yml 文件的服务定义中通过 deploy -> resources -> limits 来配置。
  • 监控: 部署后,需要建立监控机制 📊 来跟踪 Redis 实例的健康状况、内存使用、连接数和复制延迟等。

这样,你就成功地在一台 Linux 服务器上使用 Docker 搭建了一个 Redis 一主二从的复制结构啦!👍


三、 主从复制的数据同步原理是什么?

这个过程分为两个阶段:

  • a. 首次连接/全量复制 (小弟刚入门,大哥先给一本完整的秘籍 📖)

    1. 握手 🤝:小弟启动后,会主动向大哥发送一个 PSYNC (或者旧版的 SYNC) 命令,告诉大哥:“大哥,我是新来的(或者断线重连的),我想跟你混,告诉我你的ID和现在的数据进度(偏移量)”。
    2. 大哥准备:大哥收到后,会执行一个 BGSAVE 命令,在后台生成一个当前数据的快照(RDB文件)📸。这就像大哥把目前所有的武功秘籍复印一份。
    3. 缓冲命令 ⏳:在生成快照期间,大哥如果又收到了新的写命令(比如又学了新招式),会先把这些新命令缓存起来,不立刻发给这个正在等待快照的小弟。
    4. 发送快照 📤📁:大哥把生成的RDB快照文件发给小弟。
    5. 小弟加载 📥⏳:小弟收到快照文件后,会清空自己原来的旧数据(如果有的话),然后加载这个RDB文件,这样小弟的数据就和大哥生成快照那个时间点完全一致了。
    6. 发送缓冲命令 📨:大哥把在生成快照期间缓存起来的新命令,再发给小弟。小弟执行这些命令,追上大哥最新的状态。
    7. 完成 👍✅:至此,小弟的数据就和大哥完全同步了。这个过程叫“全量复制”。
  • b. 持续同步/增量复制 (入门后,大哥有新招式随时教 🏃‍♂️💨)

    • 全量复制完成后,大哥每次执行一个“写”命令(如 SET, DEL, INCR 等),都会把这个命令实时地、异步地发送给所有跟着他的小弟 📡。
    • 小弟收到命令后,就在自己这边也执行一遍同样的命令,从而保持和大哥的数据一致。
    • 这个过程是持续不断的,只要主从连接正常,大哥一有动作,小弟马上跟着学。
  • 断线重连优化 (小弟临时掉线了怎么办?🔗❓)

    • Redis 2.8 版本之后引入了 PSYNC 命令,支持部分重同步(Partial Resynchronization)
    • 大哥会维护一个“复制积压缓冲区”(Replication Backlog),这是一个固定大小的队列,记录了最近发送给小弟们的命令。
    • 如果小弟只是短暂断线(比如网络抖动),重连时,小弟会告诉大哥自己断线前的“进度”(复制偏移量 offset)。
    • 大哥检查这个进度,如果在自己的积压缓冲区里还能找到小弟断线后产生的所有新命令,那么大哥就只把这些增量的命令发给小弟 🩹➡️。小弟执行完就追上了。这样就避免了代价很高的全量复制。
    • 如果小弟断线时间太长,或者积压缓冲区太小,大哥找不到小弟需要的增量信息了,那就只能辛苦一点 😥,再来一次全量复制 🏋️‍♀️。

四、 主从复制的优缺点是什么?

  • 优点 (好处 👍)

    • 高可用性基础 🛡️:是Redis Sentinel(哨兵)和 Redis Cluster(集群)实现自动故障转移和高可用的基石。
    • 读扩展性好 📈:可以通过增加Slave节点来线性地扩展系统的读性能。
    • 数据冗余 📑:提供了数据的热备份。
  • 缺点 (不足之处 👎)

    • 写能力无扩展 ✍️➡️:所有写操作都必须经过Master,Master的写压力无法通过增加Slave来分摊。单点写性能瓶颈 🏺。
    • 主节点故障问题 (若无哨兵等机制) ⚠️:如果Master宕机,需要手动将一个Slave提升为新的Master,并且通知应用切换连接,这期间服务会中断。需要配合哨兵或集群才能实现自动故障恢复。
    • 数据一致性问题 ⏰:主从复制是异步的。命令从Master发送到Slave需要时间,Slave执行也需要时间。所以在极短的时间窗口内,Slave的数据可能稍微落后于Master(比如Master刚写完一个值,还没来得及传给Slave,这时去Slave读可能读到旧值)。这叫最终一致性,对于要求强一致性的场景可能有影响。
    • 全量复制开销 🏋️‍♀️💸:首次连接或断线重连时间过长导致的全量复制,会对Master造成CPU、内存和网络带宽的压力,尤其是在数据量大的情况下。

五、 总结

Redis主从复制就是找一堆小弟(Slaves)跟着大哥(Master)学习。好处是大哥倒了有人顶上(高可用备份 💪),人多力量大能帮大哥分担读数据的活儿(读写分离/负载均衡 🤝🚀)。搭建起来就是在小弟的配置文件里写上大哥的地址和密码 ⚙️🔑。同步原理是,新来的小弟先拿一份大哥的完整笔记(全量复制 📸➡️📖),之后大哥有新动作就实时通知小弟们跟着做(增量复制 🏃‍♂️💨)。缺点是写操作还得大哥一个人扛 ✍️➡️,大哥真挂了得有人手动扶小弟上位(除非有哨兵帮忙 ⚠️),而且小弟学东西总会慢半拍(数据有延迟 ⏰)。

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

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

相关文章

k8s 1.30.6版本部署(使用canal插件)

#系统环境准备 参考 https://blog.csdn.net/dingzy1/article/details/147062698?spm1001.2014.3001.5501 #配置下载源 curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key |gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyri…

机器学习的一百个概念(7)独热编码

前言 本文隶属于专栏《机器学习的一百个概念》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…

RHCSA复习

在Linux中, wrx 分别代表写(write)、读(read)和执行(execute)权限,它们对应的权限值分别是: - r (读权限):权限值为4。 - w &am…

“乐企“平台如何重构业财税票全流程生态?

2025年,国家税务总局持续推进的"便民办税春风行动"再次推进数字化服务升级,其中"乐企"平台作为税务信息化的重要载体,持续优化数电票服务能力,为企业提供更高效、更规范的税务管理支持。在这一背景下&#xf…

Android audio(6)-audiopolicyservice介绍

AudioPolicyService 是策略的制定者,比如某种 Stream 类型不同设备的音量(index/DB)是多少、某种 Stream 类型的音频数据流对应什么设备等等。而 AudioFlinger 则是策略的执行者,例如具体如何与音频设备通信,维护现有系…

Boost库搜索引擎项目(版本1)

Boost库搜索引擎 项目开源地址 Github:https://github.com/H0308/BoostSearchingEngine Gitee:https://gitee.com/EPSDA/BoostSearchingEngine 版本声明 当前为最初版本,后续会根据其他内容对当前项目进行修改,具体见后续版本…

git分支合并信息查看

TortoiseGit工具 1、选择"Revision graph" 2、勾选view中的 Show branchings and merges Arrows point towards merges 3、图案说明 红色部分‌:代表当前分支 橙色部分‌:代表远程分支 黄色部分‌:代表一个tag 绿色部分‌&#xf…

Java学习笔记(多线程):ReentrantLock 源码分析

本文是自己的学习笔记,主要参考资料如下 JavaSE文档 1、AQS 概述1.1、锁的原理1.2、任务队列1.2.1、结点的状态变化 1.3、加锁和解锁的简单流程 2、ReentrantLock2.1、加锁源码分析2.1.1、tryAcquire()的具体实现2.1.2、acquirQueued()的具体实现2.1.3、tryLock的具…

在C++11及后续标准中,auto和decltype是用于类型推导的关键特性,它们的作用和用法。

在C11及后续标准中,auto和decltype是用于类型推导的关键特性,它们的作用和用法有所不同。以下是详细说明: 1. auto 关键字 基本作用 自动推导变量的类型(根据初始化表达式)主要用于简化代码,避免显式书写…

Linux:进程程序替换execl

目录 引言 1.单进程版程序替换 2.程序替换原理 3.6种替换函数介绍 3.1 函数返回值 3.2 命名理解 3.3 环境变量参数 引言 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),我们所创建的所有的子进程,执行的代码&#x…

LeetCode.02.04.分割链表

分割链表 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1: 输入:head [1,4,3,2,5,2], x …

Johnson算法 流水线问题 java实现

某印刷厂有 6项加工任务J1,J2,J3,J4,J5,J6,需要在两台机器Mi和M2上完 成。 在机器Mi上各任务所需时间为5,1,8,5,3,4单位; 在机器M2上各任务所需时间为7,2,2,4,7,4单位。 即时间矩阵为: T1 {5, …

按键++,--在操作uint8_t类型(一个取值为1~10的数)中,在LCD中显示两位数字问题

问题概况 在执行按键,--过程中,本来数值为1~10.但是在执行过程中,发现数值在经过10数值后,后面的“0”会一直在LCD显示屏中显示。 就是执行操作中,从1,2,3,4,5&#xf…

【QT】QTreeWidgetItem的checkState/setCheckState函数和isSelected/setSelected函数

目录 1、函数原型1.1 checkState/setCheckState1.2 isSelected/setSelected2、功能用途3、示例QTreeWidget的checkState/setCheckState函数和isSelected/setSelected这两组函数有着不同的用途,下面具体说明: 1、函数原型 1.1 checkState/setCheckState Qt::CheckState QTr…

005 vue项目结构 vue请求页面执行流程(vue2)

文章目录 vue项目结构vue请求页面执行流程main.jsrouterHelloWorld.vueApp.vueindex.html vue项目结构 config目录存放的是配置文件,比如index.js可以配置端口 node_modules存放的是该项目依赖的模块,这些依赖的模块在package.json中指定 src目录分析 1…

汇丰xxx

1. Spring Boot 的了解,解决什么问题? 我的理解: Spring Boot 是一个基于 Spring 框架的快速开发脚手架,它简化了 Spring 应用的初始搭建和开发过程。解决的问题: 简化配置: 传统的 Spring 应用需要大量的…

基于 Spring Boot 瑞吉外卖系统开发(一)

基于 Spring Boot 瑞吉外卖系统开发(一) 系统概述 系统功能 技术选型 初始项目和数据准备 初始项目和SQL文件下载 创建数据库并导入数据 打开reggie项目 运行效果 主函数启动项目,访问URL: http://127.0.0.1:8080/backend/pag…

大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具

大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具 Coze、Dify、FastGPT 和 MaxKB 都是旨在帮助用户构建基于大型语言模型 (LLM) 的智能应用的平台。它们各自拥有独特的功能和侧重点,以下是对它们的简要对比: Coz…

【项目管理】第6章 信息管理概论 --知识点整理

项目管理 相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应&…

Zapier MCP:重塑跨应用自动化协作的技术实践

引言:数字化协作的痛点与突破 在当今多工具协同的工作环境中,开发者与办公人员常常面临数据孤岛、重复操作等效率瓶颈。Zapier推出的MCP(Model Context Protocol)协议通过标准化数据交互框架,为跨应用自动化提供了新的…