redis主从复制
Redis 主从复制全流程深度解析
Redis 主从复制(Master-Slave Replication)全流程解析
Redis 主从复制是实现数据备份、读写分离、高可用的核心机制,简单说就是「主节点(Master)写数据,从节点(Slave)同步主节点数据并提供读服务」。下面从复制触发方式、完整同步流程、增量同步流程、核心细节四个维度,把整个过程讲透。
一、先明确核心角色与目标
- 主节点(Master):可读写,负责接收所有写操作,是数据的「源头」;
- 从节点(Slave):只读(默认),唯一任务是同步 Master 数据,分担读压力;
-
核心目标:
- 数据冗余:Master 故障时,Slave 可升级为 Master 保障可用性;
- 读写分离:Master 写、Slave 读,提升整体并发能力;
- 负载均衡:分散读请求到多个 Slave。
二、复制的触发方式
从节点主动发起复制,有 2 种配置方式:
1. 配置文件方式(永久生效)
在 Slave 节点的
redis.conf 中添加:# 指定主节点IP和端口
replicaof <master-ip> <master-port>
# 如果主节点设置了密码,需要配置认证
masterauth <master-password>
2. 运行时命令方式(临时生效,重启失效)
登录 Slave 节点执行:
# 关联主节点
127.0.0.1:6380> replicaof 127.0.0.1 6379
# 主节点有密码时,先认证
127.0.0.1:6380> auth <master-password>
三、完整同步(全量复制):Slave 首次连接 Master
这是最核心的流程,发生在 Slave 第一次连接 Master、或 Slave 断线后重连但无法进行增量同步时。整个过程分 6 步:
步骤 1:建立套接字连接(Socket)
- Slave 启动后,向 Master 发起 TCP 连接请求;
- Master 接收连接,创建「复制专用」套接字,双方建立长连接;
- 若连接失败(如网络不通、Master 密码错误),Slave 会每隔 1 秒重试(可通过
replica-ping-replica-period配置)。
步骤 2:全量同步前的「握手协商」
- Slave 向 Master 发送
PING命令,检测 Master 可用性; - Master 回复
PONG,确认自身正常; - 若 Master 设置了
requirepass,Slave 发送AUTH命令+密码,认证通过后才能继续; - Slave 发送
REPLCONF listening-port <自身端口>,告诉 Master 自己的监听端口; - Slave 发送
REPLCONF capa eof capa psync2,声明支持的复制能力(如 psync2 协议、EOF 检测)。
步骤 3:Slave 发起全量同步请求(PSYNC)
Slave 发送
PSYNC ? -1 命令:?:表示 Slave 不知道 Master 的「运行 ID」(首次连接);-1:表示 Slave 没有偏移量(offset),需要全量同步。
步骤 4:Master 生成 RDB 快照(核心)
- Master 收到
PSYNC后,执行BGSAVE命令,fork 子进程生成 RDB 快照文件; - 生成 RDB 期间,Master 会把新收到的写命令(如 SET、HSET)写入「复制缓冲区」(repl backlog),避免数据丢失。
步骤 5:Master 发送 RDB 文件给 Slave
- Master 完成 RDB 生成后,通过套接字将 RDB 文件发送给 Slave;
- Slave 接收 RDB 文件,先清空自身原有数据(避免旧数据干扰),然后加载 RDB 到内存,恢复 Master 的数据快照。
步骤 6:Master 发送复制缓冲区的增量命令
- RDB 发送完成后,Master 把「生成 RDB 期间」写入复制缓冲区的所有写命令,一次性发送给 Slave;
- Slave 执行这些增量命令,使自身数据与 Master 完全一致;
- 至此,全量同步完成,进入「增量同步阶段」。
四、增量同步:正常运行时的实时同步
全量同步完成后,Master 与 Slave 进入稳定的增量同步阶段,核心是「Master 有写操作就实时推给 Slave」:
- Master 每执行一个写命令,都会把命令写入「复制缓冲区」(环形缓冲区,默认 1MB,可通过
repl-backlog-size调整); - Master 通过已建立的长连接,将写命令实时发送给所有 Slave;
- Slave 接收命令后,立即执行,保证与 Master 数据一致;
- 每个 Slave 会记录自己同步到的「偏移量(offset)」,Master 也会记录每个 Slave 的 offset,用于异常重连时判断是否需要全量同步。
五、断线重连后的同步逻辑(部分同步)
如果 Slave 因网络问题断线,重连后不会直接触发全量同步,而是先尝试「部分同步」:
-
Slave 重连 Master 后,发送
PSYNC <master-runid> <slave-offset>:master-runid:上次连接的 Master 运行 ID(唯一标识 Master);slave-offset:Slave 最后同步到的偏移量;
-
Master 检查:
- 若
master-runid匹配(还是同一个 Master),且 Slave 的 offset 落在「复制缓冲区」的有效范围内 → 只发送 offset 之后的增量命令(部分同步); - 若
master-runid不匹配(Master 更换),或 offset 超出缓冲区范围 → 触发全量同步。
- 若
六、核心细节与关键配置
1. 复制缓冲区(Repl Backlog)
- 作用:缓存 Master 最新的写命令,供 Slave 断线重连时增量同步;
- 配置:
repl-backlog-size 1mb(默认),repl-backlog-ttl 3600(缓冲区无 Slave 连接时的存活时间); - 建议:读写频繁的场景,调大
repl-backlog-size(如 10MB),减少全量同步概率。
2. 复制偏移量(Offset)
- Master 和 Slave 各自维护 offset:Master 记录发送的字节数,Slave 记录接收的字节数;
-
可通过
info replication查看:# Master 侧 master_repl_offset: 12345 # Slave 侧 slave_repl_offset: 12345 # 与 Master 一致则同步正常
3. 运行 ID(Run ID)
- Master 启动时生成的唯一 ID(如
878f966e7a97d889),Slave 会记录该 ID; - 若 Master 重启,Run ID 会变化,Slave 重连时会触发全量同步(Redis 4.0+ 支持
replica-no-one-detected优化)。
4. 从节点只读
- 默认 Slave 只读(
slave-read-only yes),防止误写; - 如需临时写(如调试),可执行
config set slave-read-only no,但生产环境禁止。
5. 复制超时
- 配置:
repl-timeout 60(默认 60 秒),超过该时间无通信则断开连接; - 需保证
repl-timeout>repl-ping-replica-period(Slave 向 Master 发送 PING 的间隔,默认 10 秒)。
七、常见问题与避坑
-
全量同步耗时过长:
- 原因:Master 数据量大,RDB 生成/传输慢;
- 解决:调大 Master 的
dbfilename所在磁盘 IO 优先级,使用高速网络,或分批次同步(如先同步冷数据)。
-
Slave 数据延迟:
- 原因:网络延迟、Master 写压力大、Slave 执行命令慢;
- 解决:增加 Slave 节点分担读压力,优化 Master 写性能,缩短复制缓冲区超时时间。
-
Master 故障后 Slave 数据不一致:
- 原因:断线时 Master 有未同步的命令;
- 解决:结合哨兵(Sentinel)或 Redis Cluster,自动切换 Master 并保证数据一致性。
总结
- 全量同步:Slave 首次连接/重连无法增量同步时触发,流程为「建连接→协商→Master 生成 RDB→发送 RDB→发送增量命令→Slave 加载」;
- 增量同步:正常运行时,Master 实时推送写命令给 Slave,通过 offset 保证数据一致;
- 断线重连:优先尝试部分同步(基于复制缓冲区),失败则触发全量同步,核心依赖 Run ID 和 offset。
Redis 主从复制是哨兵(Sentinel)和集群(Cluster)的基础,掌握这个流程后,理解高可用架构会更轻松。如果需要,我可以补充「主从复制+哨兵」的完整部署示例。

浙公网安备 33010602011771号