Redis 主从复制详解(基于 6.0.10 版本)
Redis 主从复制(Master-Slave Replication)是实现高可用和读写分离的核心机制,通过将主节点(Master)的数据同步到从节点(Slave),避免单点故障并分担读压力。本文详细解析主从复制的原理、配置方式、常见模式及哨兵(Sentinel)自动故障转移机制。
主从复制核心原理
主从复制通过 PSYNC 命令 实现数据同步,支持全量同步和部分同步两种模式,兼顾初次复制和断线重连场景。
PSYNC 命令的两种模式
- 全量同步(Full Resync):适用于初次复制(Slave 首次连接 Master)。
流程:- Slave 向 Master 发送
PSYNC ? -1
(表示需要全量同步)。 - Master 生成 RDB 快照,发送给 Slave;同时缓存快照生成期间的写命令(复制积压缓冲区)。
- Slave 加载 RDB 快照,再执行缓存的写命令,最终与 Master 数据一致。
- Slave 向 Master 发送
- 部分同步(Partial Resync):适用于断线重连(Slave 短暂断开后重新连接)。
流程:- Slave 重连后,向 Master 发送
PSYNC <master_runid> <offset>
(携带上次同步的 Master 标识和偏移量)。 - Master 验证master_runid(自身标识)和offset(同步偏移量):
- 若有效(偏移量在复制积压缓冲区内),仅发送偏移量后的增量写命令。
- 若无效(如 Master 重启或偏移量过期),触发全量同步。
- Slave 重连后,向 Master 发送
核心概念
master_runid
:Master 的唯一标识(每次重启会变化),用于 Slave 验证连接的是否为同一 Master。- 复制偏移量(Offset):Master 和 Slave 分别维护的计数器,记录已同步的字节数(确保数据一致性)。
- 复制积压缓冲区:Master 端的环形缓冲区(默认 1MB),存储最近的写命令,用于部分同步。可通过
repl-backlog-size
调整大小(如repl-backlog-size 10mb
)。
主从复制配置
主从复制采用 “配从不配主” 原则:只需配置 Slave 指向 Master,Master 无需额外配置。
环境准备
以 “一主两从” 为例(单台机器模拟,通过不同端口区分节点):
- Master:端口 6379
- Slave1:端口 6380
- Slave2:端口 6381
配置步骤
(1)启动节点
分别通过配置文件启动 3 个 Redis 节点(配置文件示例 redis6379.conf
):
1 | # Master 配置(redis6379.conf) |
1
2
3
启动命令:
1 | redis-server redis6379.conf |
(2)动态配置从节点
若未在配置文件中预设 replicaof
,可通过命令临时配置(重启后失效):
1 | 连接 Slave1(6380 端口) |
(3)验证主从关系
通过 info replication
命令查看节点角色和同步状态:
Master 节点(6379):
1
2
3
4
5
6127.0.0.1:6379> info replication
Replication
role:master
connected_slaves:2 # 2 个从节点
slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=100,lag=1Slave 节点(6380):
1
2
3
4
5
6
7127.0.0.1:6380> info replication
Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up # 与 Master 连接正常
slave_read_only:1 # 从节点默认只读
主从复制核心特性
- 读写分离:Master 支持读写,Slave 默认只读(
slave-read-only:1
),不能写(error) READONLY You can’t write against a read only replica。可通过配置修改但不推荐。 - 数据同步:Master 写入数据后,自动同步到所有 Slave(最终一致性,存在微小延迟)。
- Master 故障后:Slave 仍保持连接状态(
master_link_status:down
),等待 Master 恢复;若需切换主节点,需手动执行replicaof no one
(Slave 变 Master)。
常见主从模式
1. 一主两仆(单 Master 多 Slave)
- 结构:1 个 Master 同步数据到多个 Slave(如 6379 → 6380、6381)。
- 优势:简单易配置,适合读压力大的场景(Slave 分担读请求)。
- 劣势:Master 单点故障时,需手动切换;所有 Slave 直接从 Master 同步,可能加重 Master 负担。
2. 薪火相传(Slave 作为下一级 Slave 的 Master)
- 结构:Master → Slave1 → Slave2(如 6379 → 6380 → 6381),Slave1 同时作为 Slave2 的 Master。
- 优势:减轻 Master 的同步压力(Slave2 从 Slave1 同步,而非直接从 Master)。
- 劣势:数据同步延迟累积(Slave2 比 Slave1 延迟更高);某一级 Slave 故障会影响下游节点。
3. 哨兵模式(Sentinel):自动故障转移
哨兵模式通过监控主从节点状态,在 Master 故障时自动选举新 Master,实现高可用(无需人工干预)。
哨兵核心功能
- 监控:定期检查 Master 和 Slave 是否存活。
- 通知:当节点故障时,通过 API 通知管理员或应用程序。
- 自动故障转移:Master 故障后,自动将最优 Slave 升级为新 Master,并调整其他 Slave 指向新 Master。
哨兵配置(redis-sentinel.conf)
1 | # 监控的 Master 名称、IP、端口,quorum 表示至少需要 1 个哨兵同意才判定 Master 故障 |
启动哨兵
1 | 哨兵默认端口 26379,可通过 --port 指定其他端口 |
哨兵工作流程
- 监控阶段:哨兵每隔 10 秒向 Master 发送
INFO
命令,获取主从拓扑关系;每隔 1 秒向所有节点发送PING
命令,检测存活状态。 - 故障判定:若 Master 超过
down-after-milliseconds
未响应,哨兵标记其为 “主观下线”;若超过quorum
个哨兵均判定其下线,则标记为 “客观下线”。 - 选举新 Master:
- 筛选 Slave:排除下线、响应慢、与 Master 断开过久的 Slave。
- 优先级排序:优先选择
slave-priority
高的 Slave(默认 100,值越小优先级越高);若优先级相同,选择复制偏移量最大(数据最新)的;若仍相同,选择 ID 最小的。
- 故障转移:
- 向选中的 Slave 发送
replicaof no one
,使其成为新 Master。 - 向其他 Slave 发送
replicaof <新 Master IP> <端口>
,使其同步新 Master。 - 若原 Master 恢复,自动成为新 Master 的 Slave。
- 向选中的 Slave 发送
查看哨兵状态
1 | 连接哨兵(默认端口 26379) |
主从复制的作用与注意事项
核心作用
- 读写分离:Master 处理写请求,Slave 分担读请求(如报表查询、日志分析),提升吞吐量。
- 灾备容错:Slave 作为数据备份,避免 Master 单点故障导致数据丢失。
- 横向扩展:通过增加 Slave 节点扩展读能力,适应高并发场景。
注意事项
- 复制延迟:主从同步存在延迟(尤其薪火相传模式),不适合强一致性场景(如金融交易)。
- 哨兵数量:建议部署 3 个或 5 个哨兵(奇数),避免投票时出现平票(脑裂风险)。
- 复制积压缓冲区:高写入场景需调大
repl-backlog-size
(如 100MB),减少断线后全量同步的概率。 - Master 写限制:可通过
min-replicas-to-write
配置 “至少 N 个 Slave 在线才允许写”(如min-replicas-to-write 2
),避免 Master 孤立写入
v1.3.10