真实面经题目 · 原创解析
Redis 主从同步有哪些策略?
Redis 主从同步主要包括全量同步、部分重同步和命令传播三类链路。第一次复制或偏移量缺失时走全量,短暂断线且复制积压缓冲区仍保留缺失命令时走部分重同步,正常状态下主节点持续把写命令传播给从节点。
真实面经题目 · 原创解析
Redis 主从同步主要包括全量同步、部分重同步和命令传播三类链路。第一次复制或偏移量缺失时走全量,短暂断线且复制积压缓冲区仍保留缺失命令时走部分重同步,正常状态下主节点持续把写命令传播给从节点。
Redis 主从同步可以按生命周期回答。建立复制关系后,从节点向主节点发起 PSYNC。若是首次复制、复制 ID 不匹配或偏移量无法在复制积压缓冲区中找到,就进行全量同步:主节点生成 RDB 快照并发送给从节点,从节点加载快照,同时主节点把快照期间的新写命令缓存起来,加载完成后继续发送这些增量命令。若从节点只是短暂断线,重连时带上旧的 replication id 和 offset,主节点发现缺失部分还在 backlog 中,就执行部分重同步,只补发断线期间的命令。同步稳定后进入命令传播阶段,主节点把后续写命令异步发送给从节点。从节点默认异步复制,因此存在复制延迟和短暂不一致,需要用 offset、lag、backlog、WAIT 或读写策略控制风险。
全量同步用于从节点没有可复用状态的情况,例如首次建立复制、复制 ID 对不上、偏移量太旧或积压缓冲区已覆盖。主节点会生成 RDB 数据快照发送给从节点,从节点清空旧数据并加载快照。这个过程开销较大,会占用网络、磁盘和 CPU,数据量大时还会带来明显延迟和内存压力。
主节点生成和传输 RDB 不是瞬间完成的,这期间仍可能接收写命令。为了不丢数据,主节点会把快照期间的新写命令缓存在复制缓冲区中,等从节点加载 RDB 后继续发送。否则从节点只拿到快照时刻的数据,会漏掉快照生成期间的更新。
部分重同步用于网络抖动或从节点短暂断开后的恢复。从节点重连时带上自己已复制到的 offset 和主节点 replication id,主节点检查缺失命令是否仍在复制积压缓冲区。如果还在,就只补发缺失的写命令,避免重新传整份 RDB。backlog 大小直接影响部分重同步成功率。
完成初始同步后,主从进入持续复制状态。主节点执行写命令后,把命令按顺序传播给从节点,从节点重放命令来保持数据接近一致。Redis 复制默认是异步的,主节点不会等待所有从节点确认后再返回客户端,所以从库可能短暂落后,故障切换时也可能丢失未复制完成的数据。
生产环境要避免频繁全量同步,重点关注 repl_backlog_size、从库延迟、网络稳定性和大 key 写入。读请求打到从库时要接受延迟一致性,强一致读要回主库或使用额外确认机制。级联复制可以减轻主节点复制压力,但会增加链路延迟和故障排查复杂度。
首次复制、主从复制 ID 不匹配、从节点 offset 太旧、backlog 中找不到缺失命令,或者复制状态无法复用时会触发全量同步。
backlog 保存主节点最近传播的写命令。断线从节点重连后,如果缺失的 offset 区间仍在 backlog 中,主节点就能只补发这段命令;否则只能重新全量同步。
不是,默认是异步复制。从节点可能落后主节点,主节点故障时也可能存在未复制到从节点的写入。可以用 WAIT 等机制提高确认强度,但仍要理解它和严格强一致不同。
全量同步需要生成、传输和加载 RDB,会消耗磁盘、网络、CPU 和内存。大实例频繁全量同步可能拖慢主节点,甚至影响线上读写延迟。