Redis 主从同步完整深度详解
核心概念 Redis 主从同步是全量同步和增量同步的组合,psync2.0 实现断点续传,避免全量同步风暴。
1. 主从复制基础概念
1.1. 作用
- 数据副本:主节点写数据,从节点完整同步,实现数据冗余备份;
- 读写分离:主负责写,从分担读请求,提升并发承载;
- 高可用基础:哨兵、Redis Cluster 集群底层依赖主从复制实现故障切换。
1.2. 核心架构
- Master(主节点):唯一可写入,接收客户端写指令;
- Slave / Replica(从节点):只读,自动同步主全量+增量数据;
支持链式复制:Master → Slave1 → Slave2(级联从库,减轻主同步压力)。
1.3. 两种同步模式
- 全量同步(RDB 同步):新从库初次连接、长时间断连差距过大,主生成RDB全量文件传输;
- 增量同步(缓冲区repl_backlog):短时间断开重连,仅同步断开期间积压的命令日志。
2. 底层核心组件
2.1. replication-id(复制标识)
每个Redis实例启动生成唯一 replid(40位字符串),标识一套完整数据集。
- 主从
replid一致代表属于同一复制链; - 主节点重启、执行
flushall会生成新replid,从库触发全量同步。
2.2. offset 复制偏移量
主节点每执行一条写命令,自身master_repl_offset自增;
从库同步完命令后,记录自身slave_repl_offset;
对比两者offset差值,判断需要同步多少增量数据。
2.3. repl_backlog 复制积压缓冲区(关键)
主节点开辟一块环形内存缓冲区,存放最近执行的写命令:
- 容量由
repl-backlog-size控制,默认1MB; - 从库短暂断开,offset差距在缓冲区范围内 → 只做增量同步;
- 断开太久,offset超出缓冲区 → 强制全量同步;
生产建议调大至64MB/128MB,避免频繁全量同步。
2.4. 从库复制缓冲区(client-output-buffer)
主给每个连接的从库单独分配输出缓冲区,同步RDB、增量命令时存放临时数据;
缓冲区溢出会直接断开主从,触发重同步,需调大:
client-output-buffer-limit slave 256mb 64mb 60
3. 完整主从同步全流程(新从库初次接入)
3.1. 阶段1:握手协商(建立TCP连接)
- 从库配置
replicaof 主IP 6379,主动发起TCP 6379连接主节点; - 从发送
PING,主回复PONG,校验连通; - 从发送
REPLCONF listening-port XXXX上报自身端口; - 从发送
REPLCONF capa eof capa psync2协商新版同步协议PSYNC2; - 从发送
PSYNC replid offset:
- 首次连接无历史数据:
PSYNC ? -1 - 断线重连:带上原有replid和自身offset
3.2. 阶段2:主判断同步方式
- 若
replid和主不一致 / offset超出backlog缓冲区:执行全量同步; - 若replid匹配、offset存在于backlog:执行增量同步,直接补发缺失命令,流程结束。
3.3. 阶段3:全量同步完整步骤
- 主执行
bgsave后台生成当前全量RDB持久化文件; - RDB生成期间,新写入的命令持续存入
repl_backlog与该从库专属输出缓冲区; - RDB文件通过TCP流式传输给从节点;
- 从库接收完成后:
- 清空自身原有所有数据;
- 加载RDB文件,恢复完整主节点快照数据;
- 主开始传输RDB生成期间积压在缓冲区的增量写命令;
- 从逐条执行增量命令,追上主当前offset;
- 同步完成,进入持续增量同步阶段:主每一条写命令实时同步发给从。
3.4. 阶段4:持续增量同步(稳定运行阶段)
主执行任何写命令(set/hset/lpush等):
- 命令先写入自身内存;
- 同步写入repl_backlog环形缓冲区;
- 异步发送给所有在线从库;
- 从接收并回放命令,保持数据与主完全一致。
4. PSYNC1 vs PSYNC2 协议区别
- PSYNC1(Redis 2.8 ~ 4.0)
只支持简单增量,主重启后replid变更,强制全量同步。 - PSYNC2(Redis 5.0+ 默认)
新增第二复制IDreplid2,主重启会保存上一版replid到replid2;
从库重连时带上旧replid,主可复用历史backlog,避免不必要全量同步,大幅优化稳定性。
5. 链式主从复制 Master → S1 → S2
- S1作为Master的从,同时作为S2的主;
- Master只同步一份数据流给S1,由S1分发同步给下游从库;
- 优势:大量从库场景减轻主节点网络、CPU压力;
- 风险:S1宕机,下游S2同步中断;层级越多同步延迟越高。
6. 主从数据一致性与复制策略
6.1. 同步复制策略(replica-sync-mode)
6.1.1. (1)异步复制(默认)
主写完本地内存立即返回客户端成功,异步发给从;
优势:主写入性能极高;
风险:主宕机,已写入主但未同步到从的数据丢失。
6.1.2. (2)半同步复制(replica_wait_acks)
开启 min-replicas-to-write N + min-replicas-max-lag 10
主写入成功后,等待至少N个从库ack确认同步完成,才返回客户端;
折中方案,平衡性能与数据安全,生产建议开启。
6.2. 从库只读控制
默认 replica-read-only yes,禁止从库写入,避免主从数据分裂;
业务读写分离只读查询走从,写统一走主。
7. 主从同步常见故障&原因
7.1. 频繁全量同步
- repl-backlog-size 缓冲区过小;
- 网络波动大,从频繁断开重连;
- 主节点重启生成新replid;
- 从库输出缓冲区溢出断开连接。
优化:调大backlog、调大slave输出缓冲区、稳定机房网络。
7.2. 主从数据不一致
- 人为在从库执行写操作(关闭replica-read-only);
- 主开启RDB/AOF持久化失败,内存数据丢失重启;
- 网络丢包、同步命令截断;
- 低版本Redis同步BUG。
7.3. 主从断开同步
- 防火墙/安全组拦截6379端口;
- 主从时间不同步、TCP心跳超时;
- 输出缓冲区超限,主主动踢掉从库;
- 内存打满触发OOM杀死Redis进程。
7.4. 同步延迟过高
- 主写入QPS极高,单从库同步线程追赶不上;
- 从库磁盘性能差,回放命令刷盘慢;
- 链式复制层级过多;
- 主CPU耗尽,无法及时分发同步命令。
8. 生产优化最佳实践
- 调大repl-backlog-size,根据写入量设64M~128M,减少全量同步;
- 调整slave客户端输出缓冲区,避免同步连接被断开;
- 开启半同步min-replicas-to-write,降低数据丢失风险;
- 主节点必须开启持久化RDB+AOF,防止重启数据清空;
- 读写分离查询分摊至从库,降低主压力;
- 多从库场景使用链式复制,减轻主网络IO;
- 监控指标:
master_repl_offset、slave_repl_offset、复制延迟、同步状态; - 禁止手动在从库执行写命令,保持replica-read-only开启。
9. 主从复制与哨兵/集群的关系
- 哨兵Sentinel:基于主从,监控所有节点,主故障自动提升最优从为新主,自动切换其余从复制新主;
- Redis Cluster:每个分片内部一套主从,分片间通过槽位分片,主从负责分片数据备份与读分离。
10. 面试核心速记总结
- 主从同步分全量RDB同步、增量backlog同步;
- 核心标识:replid复制ID、offset偏移量、repl_backlog环形缓冲区;
- 新从库完整流程:TCP握手协商PSYNC → 全量RDB传输加载 → 回放积压增量命令 → 持续异步同步;
- PSYNC2支持主重启后复用旧缓冲区,减少全量同步;
- 复制模式:异步(高性能)、半同步(数据更安全);
- 高频问题:频繁全量同步根源是backlog过小/网络不稳定;
- 链式复制减轻主压力,但会增加同步延迟;
- 哨兵、集群均依赖主从复制实现数据冗余与故障切换。
关联文档