Redis 主从复制原理
1. 工作原理概述
Redis 主从复制本质上是从节点主动向主节点请求数据同步的过程。它通过两种方式来完成数据的同步:
- **全量复制:当从节点第一次连接主节点,或者无法进行增量复制时,主节点会把所有数据完整地同步给从节点
- **增量复制:在主从连接断开后重新连接时,主节点会尝试只同步断开期间产生的写命令,以减少数据同步的开销
2. 复制过程详解
2.1 建立连接与请求同步
从节点启动后,会根据配置文件中的 slaveof <master_ip> <master_port>
命令,向主节点发起连接。一旦连接建 立,从节点会发送 PSYNC ? -1
命令,表明它希望进行同步,并请求主节点的复制ID和复制偏移量
2.2 全量复制
全量复制是数据同步的“大动作”,通常发生在以下情况:
- 从节点首次连接主节点
- 主从连接断开时间过长,无法进行增量复制
这个过程主要分为以下几个步骤:
- 主节点执行
BGSAVE
:主节点会创建一个子进程,将当前内存中的所有数据快照保存到一个 RDB 文件中。这个过程是非阻塞的,主节点仍然可以继续处理客户端的请求 - 主节点发送 RDB 文件:一旦 RDB 文件生成完毕,主节点会将其通过网络发送给从节点
- 主节点缓存新命令:在 RDB 文件生成和传输期间,主节点会将所有新产生的写命令缓存在一个复制积压缓冲区中
- 从节点清空并加载数据:从节点接收到 RDB 文件后,会先清空自身所有旧数据,然后加载 RDB 文件。加载完成后,从节点就拥有了与主节点在 RDB 生成那一刻完全一致的数据
- 主节点发送缓存命令:RDB 加载完成后,主节点会将之前在缓冲区中缓存的所有新命令发送给从节点,从节点接收并执行这些命令,从而实现最终的数据同步
2.3 增量复制
为了避免每次短暂的网络中断都触发耗时的全量复制,Redis 2.8 及以上版本引入了增量复制。它的核心在于:
- 复制偏移量:主从节点都会维护一个偏移量,记录已经同步了多少字节的数据
- 复制积压缓冲区:主节点会维护一个固定大小的循环缓冲区。所有新的写命令都会被写入这个缓冲区
当主从连接断开后,从节点会记住自己的复制偏移量。重新连接时,它会发送 PSYNC <master_replid> <offset>
命令,请求从指定偏移量开始同步
主节点收到请求后,会检查从节点请求的偏移量是否还在自己的复制积压缓冲区中:
- 如果在:说明缓冲区里有从节点需要的数据。主节点会从缓冲区中找到对应的数据,并发送给从节点,从而快速完成同步
- 如果不在:说明连接中断时间太长,缓冲区中的旧数据已经被新数据覆盖了。此时,主节点会强制执行全量复制
3. Redis 主从复制的优缺点
优点
- 读写分离:可以将大量的读请求分发到从节点,减轻主节点的压力,提高系统的并发处理能力
- 数据备份:从节点作为主节点的数据热备,可以在主节点故障时提供数据保障
- 高可用性:配合哨兵(Sentinel)或集群(Cluster)模式,可以实现故障自动转移,保证服务的高可用
缺点
- 异步复制:主从复制是异步的,主节点将数据同步给从节点是有一个延时的。如果主节点在同步完成前发生故障,可能会造成少量数据丢失
- 配置复杂性:需要额外的服务器资源来部署从节点,并且需要进行维护和监控,增加了系统的复杂性