Redis:主从复制
为什么要主从复制?
Redis 主从复制是一种数据复制机制,允许从服务器(Slave)从主服务器(Master)复制数据,从而实现数据的冗余备份、读写分离和负载均衡。
数据安全与高可用:通过将主服务器数据复制到从服务器,实现数据冗余。当主服务器出现故障时,可将从服务器提升为主服务器继续服务,避免数据丢失和业务中断,保障数据安全和系统高可用性。

读写性能优化:能实现读写分离,把读操作分发到从服务器,减轻主服务器压力,提高系统并发处理能力,让系统能应对大量读请求,提升整体性能。

配置
配置文件方式
在从服务器的配置文件(redis.conf
)中,添加以下配置:
replicaof <master-ip> <master-port>
replicaof 127.0.0.1 6379
命令行方式
在从服务器启动后,可以使用 REPLICAOF
命令动态设置主服务器:
REPLICAOF 127.0.0.1 6379
如果要取消复制关系,可以使用:
REPLICAOF NO ONE
slave-read-only
默认配置是slave-read-only=no
,从节点默认是只读的,但可以配置为接受写操作。然而,直接对从节点进行写操作可能导致数据不一致,因此一般不建议这样做。
INFO replication
Redis 中用于获取复制相关信息的命令,它可以获取关于主从复制状态的详细信息。
工作原理
- 从节点连接主节点:从节点通过发送
PSYNC
命令请求与主节点进行同步。 - 数据同步:
- 完整同步:在初次复制或无法进行部分同步时,主节点会生成当前数据的快照(RDB文件),并将其发送给从节点。从节点接收并加载该快照,实现数据同步。
- 部分同步:当网络中断后重新连接且条件满足时,主节点仅将中断期间的数据更改发送给从节点,减少数据传输量。
- 命令传播:数据同步完成后,主节点会将新的写操作命令异步地发送给从节点,确保数据的一致性。
replication ID
当 Redis 实例首次启动时,会自动生成一个初始的 replication ID。若发生主节点故障转移,新提升为主节点的从节点会生成新的 replication ID。这能确保在主节点变更时,从节点可以依据新的 replication ID 来确定是否需要重新进行全量复制。
offset
主节点在处理写命令时,每处理一个命令,就会将该命令的字节数累加到自身的 offset 上。主节点会把写命令发送给从节点,从节点执行这些命令后,也会将相应的字节数累加到自己的 offset 上。
协同工作
-
全量同步
-
当从节点首次连接主节点,或者 replication ID 不一致时,触发全量同步。
-
主节点生成 RDB 文件并发送给从节点,从节点加载 RDB 文件以完成数据同步。
-
-
部分同步
-
当从节点的 replication ID 与主节点一致,并且 offset 仍在主节点的复制缓冲区中时,触发部分同步。
-
主节点发送从节点缺失的命令,从节点执行这些命令以完成数据同步。
-
-
故障切换
-
当主节点故障时,哨兵模式会选举一个新的主节点。
-
新的主节点会生成一个新的 replication ID,并将旧的 replication ID 保存起来。
-
从节点通过 replication ID 和 offset 判断是否需要全量同步。
-
全量同步
- 从节点(6380)因首次进行数据复制,不知道主节点运行 ID 和复制偏移量,所以向主节点(6379)发送
psync ? -1
命令,主动发起数据同步请求 。 - 主节点接收到
psync ? -1
命令后,对其进行解析,判断出需要进行全量复制操作,然后回复 + FULLRESYNC 响应给从节点 。 - 从节点收到主节点的响应后,开始接收并保存主节点的运行信息,比如重要的主节点 replid,为后续的复制工作做准备 。
- 与此同时,主节点执行
bgsave
命令,进行 RDB 文件的持久化操作。即使主节点原本存有 RDB 文件,由于其数据进度落后,所以会重新生成 。 - 主节点完成 RDB 文件生成后,将这个包含完整数据的 RDB 文件发送给从节点。从节点接收后,将 RDB 数据保存到本地硬盘 。
- 在主节点生成 RDB 文件到从节点接收完成这段时间内,主节点把新执行的写命令写入缓冲区 。
- 当从节点保存完 RDB 文件后,主节点将缓冲区内的写命令数据,按照 RDB 的二进制格式,追加发送给从节点 。
- 从节点接收完上述所有数据后,先清空自身原有的旧数据,然后加载 RDB 文件,使自身数据与主节点达成一致 。
- 如果从节点加载 RDB 完成后,且开启了 AOF 持久化功能,它会执行
bgrewriteaof
重写操作,对在同步过程中记录的大量 AOF 数据进行压缩,完成全量同步 。

无硬盘同步是 Redis 2.8 版本后新增的一种主从数据同步方式,用于优化全量复制过程,与基于 RDB 文件传输的传统同步不同。主节点在进行全量复制时,不生成 RDB 文件到硬盘,而是直接通过网络将数据发送给从节点。主节点把数据分片,依次发送给从节点,从节点接收后进行数据还原。避免了 RDB 文件生成和磁盘 I/O 操作,减少了同步延迟,尤其在数据量较大时,能显著提升同步效率。
部分同步
- 从节点和主节点正常通信,一旦出现网络中断,若持续时间超过
repl-timeout
时间,主节点就会判定从节点故障,进而中断复制连接。 - 在主从连接中断期间,主节点依旧响应命令。但由于网络中断,这些复制命令无法及时发送给从节点,于是主节点将它们暂时存放在复制积压缓冲区
repl_backlog_buffer
中。 - 当网络恢复后,从节点再次连接上主节点。
- 从节点把之前保存的
replicationld
和offset
作为psync
的参数发送给主节点,向主节点请求进行部分复制 。 - 主节点接到
psync
请求后,先进行必要的验证。然后依据offset
去复制积压缓冲区查找对应的数据,若找到,就响应+CONTINUE
给从节点。 - 主节点将从节点需要同步的数据发送过去,从节点接收并执行这些数据后,最终实现与主节点的数据一致性 。
实时同步
在 Redis 的主从复制架构中,主节点与从节点成功建立复制连接后,主节点会通过 TCP 长连接,将接收到的修改操作源源不断地传输至从节点。从节点接收到这些操作请求后,会同步对自身数据进行修改,以此确保与主节点的数据保持一致。
这种 TCP 长连接的状态维护依赖于应用层自定义的心跳包机制,而非 TCP 协议自带的心跳功能。主从节点均设有各自的心跳检测机制,相互模拟为对方的客户端进行通信交互。
- 主节点默认每 10 秒向从节点发送
ping
命令,以此来判断从节点是否存活以及连接状态是否正常。 - 从节点则默认每秒向主节点发送
replconfack {offset}
命令,汇报自身当前的复制偏移量。
一旦主节点检测到与从节点的通信延迟超过 repl - timeout
配置的默认值 60 秒,便会判定该从节点处于下线状态,并随即断开复制客户端连接。不过,当从节点恢复连接后,心跳机制又会自动继续运行,维持主从节点间的正常通信与数据同步 。
主从结构
一主一从
一个主节点(Master)对应一个从节点(Slave)。主节点负责处理写操作,从节点负责复制主节点的数据并处理读操作。
应用场景:
-
数据备份:从节点作为主节点的备份,提高数据的可靠性。
-
读写分离:主节点处理写操作,从节点处理读操作,分担主节点的负载。
-
简单故障恢复:当主节点故障时,可以手动将从节点提升为新的主节点。
一主多从
一个主节点(Master)对应多个从节点(Slaves)。主节点负责处理写操作,多个从节点负责复制主节点的数据并处理读操作。
应用场景:
- 读多写少:适用于读请求远多于写请求的场景,如缓存系统。
- 负载均衡:通过多个从节点分担读请求,提高系统的整体性能。
- 高可用性:多个从节点可以作为主节点的备份,提高系统的容错能力。
树状结构
主节点作为根节点,从节点作为子节点,形成树形结构。例如:Master -> Slave1, Slave2
,其中 Slave1 和 Slave2 又可以有自己的从节点。
应用场景:
- 大规模分布式系统:适合需要大量从节点的场景。
统的容错能力。
树状结构
主节点作为根节点,从节点作为子节点,形成树形结构。例如:Master -> Slave1, Slave2
,其中 Slave1 和 Slave2 又可以有自己的从节点。
应用场景:
- 大规模分布式系统:适合需要大量从节点的场景。
- 分层管理:通过树形结构分层管理从节点,降低主节点的压力。