Redis 主从模式同步原理机制
Redis 主从同步原理机制,核心是基于 “日志 + 状态追踪” 的精准数据一致性保障体系,通过细化同步流程、优化异常处理、引入核心元数据,实现高效且可靠的主从数据对齐。
一、核心元数据:同步的 “导航系统”
主从节点通过 3 类核心元数据协同,精准把控同步状态,避免无效操作。
- 复制偏移量(Replication Offset)
- 主节点每发送 1 字节数据,自身偏移量 + 1;从节点每接收 1 字节,自身偏移量 + 1。
- 通过对比主从偏移量,可直接判断数据是否一致:若相等则同步完成,若不等则从节点需补全差值部分数据。
- 运行 ID(Run ID)
- 每个 Redis 节点启动时生成唯一的 40 位随机字符串,主节点的 Run ID 会同步给从节点。
- 作用:若从节点断线后重连,发现主节点 Run ID 改变(如主节点重启),则必须触发全量同步;若 Run ID 不变,再通过偏移量判断是否可增量同步。
- 复制积压缓冲区(Replication Backlog Buffer)
- 主节点维护的固定大小环形缓冲区(默认 1MB,可配置),专门存储近期执行的写命令。
- 工作逻辑:主节点执行写命令后,同时向从节点发送命令和写入缓冲区。若从节点断线时间短,重连后可根据自身偏移量,从缓冲区中读取缺失的命令(增量同步);若断线时间过长,缓冲区数据被覆盖,则触发全量同步。
二、全量同步:从 “数据克隆” 到 “状态对齐”
全量同步并非简单的 “文件拷贝”,而是主从节点的 “完整状态对齐” 过程,涉及多个关键步骤和资源协调。
- 同步触发与握手
- 从节点启动后,发送
PSYNC ? -1
命令(Redis 2.8+,替代旧版SYNC
),向主节点请求同步,其中 “?” 表示未知主节点 Run ID,“-1” 表示请求全量同步。 - 主节点响应
FULLRESYNC <runid> <offset>
,告知从节点自身 Run ID 和当前偏移量,确认启动全量同步。
- 从节点启动后,发送
- 主节点数据快照与命令缓存
- 主节点执行
BGSAVE
(后台生成 RDB 快照),过程中不阻塞读命令,但会将所有写命令暂存到 “复制缓冲区”(非积压缓冲区,专为当前全量同步临时开辟)。 - 目的:确保 RDB 文件生成期间的写操作不丢失,最终能同步到从节点。
- 主节点执行
- 从节点数据清空与加载
- 从节点接收主节点发送的 RDB 文件,先清空本地所有数据(避免旧数据干扰),再加载 RDB 到内存。
- 加载期间,从节点会处于 “不可用” 状态(默认配置),可通过
slave-serve-stale-data yes
配置,让其在加载时返回旧数据(牺牲一致性换可用性)。
- 缓存命令同步与状态对齐
- 主节点发送完 RDB 后,将 “复制缓冲区” 中的所有写命令发送给从节点。
- 从节点执行这些命令,使自身数据状态与主节点发送完 RDB 时的状态完全一致,此时主从偏移量相等,全量同步完成。
三、增量同步:实时变更的 “精准投递”
全量同步完成后,主从进入增量同步阶段,核心是 “写命令的实时、可靠投递”,依赖 Redis 的 “命令传播” 机制。
- 命令传播流程
- 主节点每执行一条写命令(如
SET
、HSET
),会先将命令写入自身的 AOF 缓冲区(若开启 AOF),再将命令发送给所有从节点。 - 从节点接收命令后,先写入自身的 “复制偏移量”,再执行命令,最后返回确认给主节点。
- 主节点每执行一条写命令(如
- 可靠性保障
- 主节点采用 “异步传播” 模式,发送命令后不等待从节点确认,避免阻塞主节点;但从节点会通过定期发送 “心跳包”(默认 1 秒一次),向主节点汇报自身当前偏移量。
- 主节点通过心跳包得知从节点的同步进度,若发现某从节点偏移量落后过多,会优先保障其命令传输,避免数据差距过大。
四、异常处理:同步中断的 “自愈机制”
针对网络波动、节点重启等异常场景,Redis 设计了分层自愈策略,减少全量同步的资源消耗。
- 断线重连的判断逻辑
- 从节点断线后,会启动重连机制(默认每隔 1 秒尝试重连)。
- 重连成功后,从节点发送
PSYNC <runid> <offset>
,携带之前记录的主节点 Run ID 和自身当前偏移量。 - 主节点判断:若 Run ID 匹配,且从节点偏移量在复制积压缓冲区的范围内(即缺失命令未被覆盖),则执行增量同步;否则,执行全量同步。
- 从节点晋升与主从切换
- 若主节点故障,可手动或通过哨兵(Sentinel)将某从节点晋升为新主节点。
- 新主节点生成新的 Run ID,其他从节点发现主节点 Run ID 变更后,会向新主节点发起全量同步,构建新的主从架构。
五、底层优化:性能与一致性的平衡
- 无盘复制(Diskless Replication)
- 默认全量同步时,主节点会先将 RDB 写入磁盘,再读取磁盘文件发送给从节点,存在磁盘 IO 开销。
- 开启无盘复制(
repl-diskless-sync yes
)后,主节点直接将BGSAVE
生成的 RDB 数据通过网络发送给从节点,跳过磁盘写入步骤,适用于磁盘 IO 性能瓶颈的场景。
- 复制限流
- 主节点通过
repl-backlog-size
控制积压缓冲区大小,避免占用过多内存;同时通过repl-ping-slave-period
调整心跳包频率,平衡网络开销。 - 从节点通过
repl-timeout
设置同步超时时间,避免因网络拥堵导致的无限等待。
- 主节点通过