Redis复制机制深挖和架构细节拆解,带你一步步看透底层原理
- 问答
- 2025-12-30 19:10:18
- 3
主要综合自 Redis 官方文档、相关技术博客如“Redis 设计与实现”等核心资料,并结合常见面试考点进行拆解)
我们来一步步拆解 Redis 的复制机制,想象一下,你有一个主 Redis 服务器(我们叫它老大),它负责处理所有的写操作(比如增删改数据),为了保证数据不丢失,并且能在老大出问题时有人能顶上,你需要找几个副手(我们叫它们从服务器,或者小弟),复制要解决的问题就是:如何让小弟们的数据和老大保持完全一致。
第一步:建立连接 - 小弟认老大
这个过程叫做“复制初始化”。(来源:Redis 官方文档 Replication 章节)
- 小弟配置:在一个从服务器(小弟)的配置文件里,或者通过客户端命令
SLAVEOF <master_ip> <master_port>,告诉它老大的地址和端口,从此,这个小弟就进入了“准备认老大”的状态。 - 小弟主动联系:从服务器会主动向主服务器发起一个 socket 连接,如果连接成功,从服务器会再专门建立一个连接用于发送后续的复制命令(
PING、REPLCONF等)。 - 身份验证:如果主服务器设置了密码(
requirepass),从服务器需要正确配置masterauth参数,在连接时提供密码,老大才会认这个小弟。 - 端口通报:从服务器连接成功后,会把自己的监听端口告诉主服务器,这样主服务器就知道通过哪个端口和从服务器进行数据同步。
第二步:全量同步 - 老大给小弟一份完整的数据快照
这是第一次同步时,或者从服务器落后太多时必须进行的过程。(来源:Redis 核心机制解析)
- 小弟请求同步:连接建立后,从服务器会发送
PSYNC命令给主服务器,请求开始数据同步。PSYNC命令会带上两个参数:主服务器的runid(运行ID,每个Redis实例启动时随机生成的一个唯一标识)和复制偏移量(offset),如果是第一次同步,从服务器不知道老大的runid和自己的进度,所以会发送PSYNC ? -1,意思是“我是新来的,给我全部数据”。 - 老大准备RDB快照:主服务器收到全量同步请求后,会立即执行
bgsave命令,在后台启动一个子进程,将当前内存中的所有数据生成一个快照文件(RDB文件),这个过程中,主服务器依然正常处理客户端的写命令。 - 记录写命令:关键的一步来了!在生成 RDB 文件的同时,主服务器会用一个专门的缓冲区(复制缓冲区,也叫复制积压缓冲区),把从开始生成 RDB 那一刻起,收到的所有新的写命令都记录下来。
- 发送RDB文件:RDB 文件生成完毕后,主服务器会把这个文件发送给从服务器,从服务器会先清空自己的旧数据(如果是第一次同步就是空的),然后加载这个 RDB 文件,这样它的数据状态就基本和主服务器开始
bgsave那个时间点一致了。 - 补发缓冲区的命令:RDB 文件加载完成后,主服务器会把第二步中记录在复制缓冲区里的所有写命令,再发送给从服务器,从服务器执行这些命令,最终使得自己的数据和主服务器当前的数据完全一致。
第三步:增量同步 - 持续保持同步

全量同步完成后,复制就进入了稳定的增量同步阶段。(来源:Redis 持久化与复制机制详解)
- 命令传播:此后,主服务器每执行一个会使数据发生改变的写命令(如
SET、LPUSH等),都会异步地将这个命令发送给所有从服务器。 - 复制偏移量:主从服务器都会维护一个复制偏移量(offset)。
- 主服务器每次向从服务器传播 N 个字节的数据,就把自己的偏移量加上 N。
- 从服务器每次收到主服务器传来的 N 个字节数据,也把自己的偏移量加上 N。
- 在正常情况下,主从服务器的偏移量是相等的,通过对比偏移量,可以判断主从数据是否一致。
- 心跳检测:从服务器默认每秒会向主服务器发送
REPLCONF ACK <offset>命令,offset是它当前的复制偏移量,这个命令有三个作用:- 检测连接状态:让主服务器知道从服务器还“活着”。
- 汇报复制进度:主服务器可以通过这个偏移量知道从服务器的同步延迟。
- 辅助实现最小延迟的复制(在某些配置下)。
关键架构细节:复制积压缓冲区
这是一个非常重要的概念。(来源:Redis 核心机制解析)
你可以把它想象成主服务器背部的一个“固定大小的队列”,在命令传播阶段,主服务器不仅把命令发给从服务器,还会在这个缓冲区里也存一份(存的是命令本身),这个缓冲区是“先进先出”的,当写满了,最早的命令就会被挤出去。

它的核心作用是解决因网络闪断导致的数据不一致。
- 场景:假设一个从服务器短暂断线了几秒钟,然后又重新连上了。
- 没有缓冲区:主服务器只能触发一次全量同步,开销巨大。
- 有缓冲区:从服务器重连后,会向主服务器发送
PSYNC <runid> <断线前的offset>,主服务器检查这个 offset 是否还在自己的复制积压缓冲区里。- 如果在:说明断线期间丢失的命令缓冲区里都有,主服务器只需要将从这个 offset 开始到缓冲区当前最新位置的所有命令,发送给从服务器即可,这就是“部分重同步”,效率远高于全量同步。
- 如果不在:说明从服务器断线太久,它需要的那个 offset 已经被挤出缓冲区了,此时主服务器只能被迫进行全量同步。
合理设置复制积压缓冲区的大小(repl-backlog-size 配置项)对于应对网络波动至关重要。
总结一下底层原理的核心链条:
从服务器通过 SLAVEOF 命令发起连接 -> 首次同步或落后太多时触发全量同步(bgsave RDB + 复制缓冲区补发)-> 正常运行时通过命令传播进行增量同步 -> 利用复制偏移量跟踪进度 -> 依靠复制积压缓冲区应对短暂断线,实现高效的部分重同步。
这个过程确保了 Redis 主从集群数据的最终一致性,是 Redis 实现高可用和读写分离的基础。
本文由畅苗于2025-12-30发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/71438.html
