Redis7学习--详解 主从复制
目录
一、前言
二、了解主从复制
1、概念介绍
2、功能
三、主从复制配置准备
1、配从(库)不配主(库)
2、权限细节
四、基本命令
五、演示
1、配置
2、一主二仆
2.1、方案一 配置文件写死
2.2 方案二 命令操作手动指定
3、薪火相传(级联结构)
4、反客为主
六、主从复制原理和工作流程
七、缺陷
一、前言
关于Redis的前几篇文章都是基于一台Redis服务器的情况下,但是我们知道在Redis的单机模式下,会出现以下问题:
面对这些问题,单机Redis服务器显然是不行的,所以就引入了本文的主要内容--主从复制。下面就看看Redis的主从复制是如何解决这些问题?是如何实现的?同时它本身又有什么缺点呢?
二、了解主从复制
1、概念介绍
主从复制(Master-Slave Replication)是数据库和分布式系统中一种常见的数据复制技术,其核心思想是将一份数据从一个主节点(Master)复制到一个或多个从节点(Slave),以实现数据冗余、读写分离、故障恢复和高可用性。
- 数据可靠性问题:单机 Redis 一旦宕机,服务完全不可用
- 读压力瓶颈:单个 Redis 实例处理所有读写请求,读压力大时性能受限
- 故障恢复时间长:从持久化文件恢复数据耗时较长
- 无水平扩展能力:单机性能有限,无法通过增加节点提高整体性能
-
主节点(Master):
- 接收客户端的写操作(如
SET
,DEL
等)。 - 将写操作同步给一个或多个从节点。
- 通常也支持读操作,但为了减轻压力,常将读请求分发到从节点。
- 接收客户端的写操作(如
-
从节点(Slave / Replica):
- 不能直接接收写请求(只读)。
- 通过复制主节点的数据保持与主节点数据一致。
- 可以处理读请求,实现读写分离。
- 在主节点故障时,可被提升为新的主节点(需配合哨兵或集群机制,后面讲)。
简单来说就是,在原来单机(本身就是主节点)的基础上增加一台或多台主机作为从节点,主节点以写为主,从节点以读为主。当主节点数据变化的时候,自动将新的数据异步同步到其他从节点上。
2、功能
-
读写分离:通过主从复制机制,Redis允许将读操作分散到多个从节点上执行,从而减轻主节点的压力,提高系统的读取性能和并发能力。
-
容灾恢复:Redis支持数据持久化(如RDB快照和AOF日志),可以在服务器重启或故障后恢复数据。此外,通过主从复制和哨兵(Sentinel)或集群(Cluster)等高可用方案,可以在主节点故障时自动切换到从节点,确保服务的连续性。
-
数据备份:Redis提供了多种数据备份方式,包括定期生成RDB文件进行全量备份,以及使用AOF日志记录所有写操作以实现增量备份。这些备份文件可以用于灾难恢复、数据迁移或创建新的从节点。
-
水平扩容支持高并发:Redis Cluster是一个分布式数据库解决方案,它允许将数据分布在多个节点上,并通过哈希槽(hash slot)机制实现数据的自动分片和路由。这不仅提高了系统的存储容量,还能够有效应对高并发访问需求,提升了整体性能和可扩展性。
三、主从复制配置准备
1、配从(库)不配主(库)
Redis主从复制的设计采用了单向配置原则
- 架构设计哲学:遵循"主节点不知道从节点存在"的原则,主节点保持无状态
- 简化主节点:主节点不需要维护从节点列表,减少主节点复杂度
- 动态扩展性:可以随时添加/移除从节点而不影响主节点
- 安全性:避免主节点被恶意从节点连接
- 故障隔离:主节点问题不会扩散到配置层面
2、权限细节
- master如果配置了 requirepass 参数,需要密码登录
- 主节点配置了密码认证(requirepass)时,slave 需要配置 masterauth来设置检验密码,否则的话master会拒绝slave的访问请求
四、基本命令
info replication
//查看复制节点的主从关系和配置信息replicaof/slaveof
//主库IP 主库端口 replicaof/slaveof这两个一样,
//一般写入进redis.conf配置文件内,在运行期间修改slave节点的信息,
//如果该数据库已经是某个数据库的从数据库,
//那么会停止和原主数据库的同步关系转而和新的主数据库同步replicaof/slaveof no one
//使当前数据库停止与其他数据库的同步,升级为主数据库
五、演示
1、配置
接下来演示 一个主机 Master 和两个从机 Slave 的架构,三台虚拟机每一台都安装Redis
设置主机的配置文件
开启daemonize yes,将 Redis 作为后台守护进程运行。
注释掉bind 127.0.0.1。默认 Redis 只监听本地回环地址(127.0.0.1),如果需要远程访问,需注释或修改此行
protected-mode no 保护模式用于在没有设置密码且没有绑定特定 IP 时,只允许本地连接。若需远程访问且设置了密码,可关闭此模式。
指定端口
指定当前工作目录,dir,设置 Redis 工作目录,RDB 快照、AOF 文件等会保存在此目录下。
pid文件名字,pidfile,指定 Redis 进程 ID 文件的路径,便于进程管理。
log文件名字,logfile,指定日志文件路径,便于查看运行日志。
requirepass 设置 Redis 的访问密码,客户端连接时需提供该密码
dump.rdb名字,可修改 RDB 快照文件的名称
aof文件,appendfilename
下步可选,非必须
从机访问主机的通行密码masterauth,必须配置使从节点能通过密码连接到主节点。主节点不需要此配置。
还需要注意防火墙配置
启动: systemctl start firewalld
关闭: systemctl stop firewalld
查看状态: systemctl status firewalld
开机禁用 : systemctl disable firewalld
开机启用 : systemctl enable firewalld添加 :firewall-cmd --zone=public --add-port=80/tcp --permanent (--permanent永久生效,没有此参数重启后失效)
重新载入: firewall-cmd --reload
查看: firewall-cmd --zone= public --query-port=80/tcp
删除: firewall-cmd --zone= public --remove-port=80/tcp --permanent
这时候主机已经准备好了,就等待从机连接了。
2、一主二仆
2.1、方案一 配置文件写死
方案一就是直接在从机的配置文件中写死,如下
上面分别是两台从机的配置文件,使用 replicaof 直接表明自己是192.168.111.169 6379这台主机的从机。并且配置通行密码masterauth使自己能通过密码连接到主机。
接着依次先后启动三台虚拟机如下
查看是否成功
1、通过主机日志查看
2、通过从机日志查看
3、通过 info replication 命令查看
验证
1、向从机中写入数据会发生什么?如下,可以看到是不行的
2、主机shutdown之后,从机会怎么办?直接变成主机还是什么都不做?
可以看到,从机不动,原地待命,从机数据可以正常使用;等待主机重启动归来
3、主机经历shutdown重启之后,之前的主从关系还在吗?从机能否顺利复制?
可以看到一切如旧。
4、假设主机启动已经一段时间了,并且已经写入了很多数据,此时一台从机连接主机,那么之前的数据从机能否读到?
是可以的,Redis 的主从复制机制保证了:新加入的从节点会获得主节点的完整数据快照,无论这些数据是何时写入的。首次连接就是“一锅端”给从机,后面就是主机写,从机跟。
补充:
- 如果 Slave2 之前已经同步过,重启后会尝试 部分同步(partial resynchronization),只同步断开期间丢失的数据(依赖复制积压缓冲区 repl_backlog_buffer)。
- 但如果缓冲区中没有足够的历史命令(比如断开太久或写入量太大),仍然会退回到全量复制。
5、某台从机down后,master继续,从机重启后它能跟上大部队吗?
是可以的
- 最理想:部分同步,快速恢复。
- 次之:全量同步,稍慢但数据一致。
- 极端情况:无法同步,需手动干预。
2.2 方案二 命令操作手动指定
第二种方案是不依靠配置文件手动指定
第一步从机停机去掉配置文件中的配置项,3台目前都是主机状态,各不从属,如下
第二步 replicaof/slaveof 主库IP 主库端口 成为主库的从机
可以看到手动照样可以成功。
但是考虑将两台从机宕机重启之后呢?效果是什么样子?如下
可以看到之前的主从关系已经没有了,都变成了主机,这是因为这些手动命令仅对当前运行实例生效。
所以配置 VS 命令的区别就是
- 配置,持久稳定
- 命令,当次生效
3、薪火相传(级联结构)
上一个slave可以是下一个slave的master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻主master的写压力
适用于大规模读写分离场景,比如几十个从节点时,级联结构更高效。
- 如果所有从节点都直接连到主节点:
- 主节点要发送 N 次复制流,网络和 CPU 压力大。
- 使用级联结构后:
- 主节点只负责同步第一个从节点(Slave1)。
- 后续的 Slave2、Slave3 等由 Slave1 来同步。
- 显著 降低主节点的负载,提高扩展性。
中途变更转向:会清除之前的数据,重新建立拷贝最新的
Redis 会:
- 断开与旧 master 的复制关系。
- 清空当前数据库数据(⚠️ 重要!)
- 向新 master 发起同步请求(通常是全量同步)。
- 接收 RDB 文件并加载,重建数据。
所以:切换 master = 数据清空 + 重新全量复制
💡 这是为了保证数据一致性,避免旧数据和新 master 数据冲突。
4、反客为主
- slaveof/replicaof no one 这条命令会让当前的 从节点(replica/slave)停止复制行为,并提升为独立的主节点(master)。
六、主从复制原理和工作流程
Redis主从复制分为全量复制和增量复制两种模式,通过PSYNC协议实现:
复制标识控制
replication ID:40位唯一字符串,标识主节点数据版本
offset偏移量:主从各自维护,记录已同步数据量(类似binlog位置)复制积压缓冲区
环形缓冲区存储最近的写命令(默认1MB)
通过repl-backlog-size参数调整,建议设置为「网络延迟×写入流量」的2倍
- slave启动,同步初请
- slave启动成功连接到master后会发送一个sync命令
- slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除
- 首次连接,全量复制
- master节点收到sync命令后会在后台开始保存快照(即RDB持久化,主从复制会触发RDB),同时收集所有接收到的用于修改数据集命令缓存起来,master节点执行RDB持久化后,master将rdb快照文件和缓存的命令发送到所有slave,已完成一次完全同步
- 而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化
- 心跳持续,保持通信
- repl-ping-replica-period 10
- master发出PING包的周期,默认是10秒
- 进入平稳,增量复制
- master 继续将新的所有收集到的修改命令自动一次传给slave,完成同步
- 从机下线,重连续传
- master 会检查backlog里面的offset,master和slave都会保存一个复制的offset怀有一个masterId
- offset 是保存在backlog 中的。master只会把已经复制的offset后面的数据赋值给slave,类似断电续传
增量同步(断线重连恢复)
而增量复制只会把主从库网络断连期间主库收到的命令,同步给从库。
触发条件:主从replication ID一致,且从节点offset在复制积压缓冲区(replication backlog) 范围内
执行流程:
- 从节点发送PSYNC
- 主节点校验offset后,发送积压缓冲区内缺失的命令。(主库会将 slave_repl_offset 和 master_repl_offset 之间的命令同步给从库即可)
- 从节点执行增量命令完成数据同步
因为 replication buffer 是一个环形的缓存,当主从库长期断开时,是有可能被覆盖掉旧的数据,这个时候是会重新发起全量复制,主库根据从库发送的 slave_repl_offset 来判断是增量还是全量的复制。
为什么全量复制使用 RDB 而不是使用 AOF 呢?
- RDB 文件是经过压缩的二进制文件,AOF 文件是记录每一次的操作,包含对同一个 key 的多次冗余操作,文件比 RDB 要大的多,使用 RDB 可以减少带宽
- RDB 是二进制数据,从库还原速度快。而 AOF 需要依次重放每一个命令,恢复速度慢。
七、缺陷
1、复制延时,信号衰减
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
2、如果主机突然意外宕机,从机只会傻傻等待,并不会自动重新推举一个新的主机,需要人工干预才行。
感谢阅读!