Redis 主从复制(Replication)的原理及作用
这是目前(2025-2026 年)生产环境中使用最广泛、最成熟的 Redis 高可用基础机制,几乎所有中大型公司都在用。
一、主从复制最核心的四个作用(为什么几乎必开)
| 作用排名 | 主要目的 | 实际收益(生产中最常提到的点) | 是否必须开启主从 |
|---|---|---|---|
| 1 | 读写分离 | 把 80~95% 的读流量打到从节点,大幅降低主节点压力 | 强烈推荐 |
| 2 | 数据冗余 & 容灾 | 主节点挂了,从节点可以秒级/分钟级接管(配合哨兵/Cluster) | 必须 |
| 3 | 数据备份(冷备/热备) | 从节点可以随时做 RDB/AOF 备份,不影响主节点性能 | 非常推荐 |
| 4 | 高可用基础 | 是 Redis Sentinel、Redis Cluster、代理层(如 Twemproxy、Codis、Redis-Cluster-Proxy)实现自动故障转移的前提 | 必须 |
一句话总结作用:
主从复制是 Redis “把一份数据安全地复制到多台机器上,并允许读流量分散”的最底层机制。
二、主从复制的完整工作流程(非常重要)
1. 从节点执行:SLAVEOF <master-ip> <master-port> 或 replicaof <master-ip> <master-port>
(Redis 5.0 后推荐使用 replicaof 指令)
↓
2. 从节点发起对主节点的连接(TCP 长连接)
↓
3. 从节点向主节点发送 PING → 主节点回复 PONG
↓
4. 从节点发送 PSYNC(Redis 2.8 之前是 SYNC)命令
- PSYNC <runid> <复制偏移量>
- 第一次复制时 runid = "?",offset = -1(全量同步请求)
↓
5. 主节点收到 PSYNC,根据情况回复两种结果:
A. +FULLRESYNC <runid> <offset>
→ 需要全量同步(首次、主从严重不一致、repl backlog 被覆盖等)
B. +CONTINUE
→ 可以继续增量同步(断开重连且偏移量还在 backlog 内)
↓
6. 全量同步阶段(最耗资源的部分)
主节点做以下动作:
1. 执行 BGSAVE(后台生成 RDB 文件)
2. 把 RDB 文件通过 socket 发给从节点
3. 在生成 RDB 期间,所有新的写命令记录到缓冲区
4. RDB 发送完毕后,把缓冲区积累的写命令也发给从节点
从节点收到 RDB 后:
1. 清空自己数据
2. 加载 RDB 文件
3. 继续接收后续增量命令
↓
7. 全量同步完成后,进入**增量同步阶段**
主节点把所有新的写命令通过**复制缓冲区(replication buffer)**实时发给所有从节点
从节点收到命令后顺序执行,保持与主节点数据一致
一句话流程总结:
第一次:全量(RDB + 缓冲区写命令)
之后:增量(实时转发写命令)
三、几个关键内部机制(面试/排障常考)
| 机制名 | 说明 | 默认值 / 重要配置项 | 生产建议 |
|---|---|---|---|
| 复制 backlog | 主节点的一个环形缓冲区,保存最近的写命令,用于支持断线重连后的增量同步 | repl-backlog-size 1MB(太小!) | 建议设 32MB~256MB(视写 QPS) |
| runid | 每个 Redis 实例启动时生成的随机字符串,用于标识主节点身份 | — | 从节点记住主节点的 runid |
| 复制偏移量(offset) | 主从各自维护,代表已经同步到的字节位置 | — | 通过 info replication 查看 |
| 磁盘less 复制 | 不写 RDB 文件,直接通过 socket 传输内存中的数据(Redis 2.8.18+) | repl-diskless-sync no | 建议开启(尤其是大内存实例) |
| 复制缓冲区(client-output-buffer-limit) | 每个从节点连接的输出缓冲区,防止从节点太慢把主节点内存撑爆 | slave-output-buffer-limit 256MB hard 等 | 根据从节点延迟调整 |
四、常见生产问题 & 对应解决思路
| 现象 | 根本原因 | 解决 / 优化方向 |
|---|---|---|
| 从节点长时间处于 fullresync | repl-backlog-size 太小,被覆盖了 | 调大 repl-backlog-size(至少 几十 MB) |
| 主节点内存暴涨 | 从节点消费慢,输出缓冲区堆积 | 调大 client-output-buffer-limit slave |
| 从节点加载 RDB 非常慢 | RDB 文件太大,网络带宽不足 | 开启 diskless 复制 + 压缩网络 |
| 主从延迟很大(秒级~分钟级) | 主节点写 QPS 高,从节点单线程执行慢 | 1. 垂直拆分 key 空间 2. 多从分担读压力 3. 考虑 Redis 7.0+ 的多线程 IO |
| 从节点重启后总是全量同步 | runid 变化 + offset 丢失 | 使用 replica-announce-ip/port 固定地址,或用 Sentinel 管理 |
五、2025-2026 年生产最推荐的配置组合(中大型业务)
# 主节点建议
repl-backlog-size 128mb # 至少 64-256MB,根据写 QPS 评估
min-replicas-to-write 1 # 至少 1 个从节点健康才允许写
min-replicas-max-lag 10 # 从节点延迟 >10s 就拒绝写
# 从节点通用
replica-read-only yes
replica-priority 100 # Sentinel 选主时权重
# 开启无盘复制(推荐)
repl-diskless-sync yes
repl-diskless-sync-delay 5 # 延迟 5 秒让多个从节点一起同步
# 输出缓冲区保护(防止慢从把主内存撑爆)
client-output-buffer-limit replica 256mb 64mb 60
一句话总结 Redis 主从复制的核心价值:
用最小的代价(一台机器的内存 + 网络带宽),换来读扩展、容灾、备份、高可用基础 四重收益,是 Redis 能支撑亿级 QPS 的基石之一。
你现在最想深入哪个部分?
- 全量同步时 RDB 生成 & 传输的详细时序?
- PSYNC 的握手协议细节?
- Sentinel + 主从复制如何实现自动故障转移?
- Redis 7.0+ 多线程 IO 对复制的影响?
- 主从复制在 Codis/Redis Cluster 中的不同表现?
告诉我,我可以继续给你展开~