### Redis 主从复制原理

**1. 工作原理概述**

Redis 主从复制本质上是**从节点主动向主节点请求数据同步**的过程。它通过两种方式来完成数据的同步：

1. **全量复制：当从节点第一次连接主节点，或者无法进行增量复制时，主节点会把所有数据完整地同步给从节点
2. **增量复制：在主从连接断开后重新连接时，主节点会尝试只同步断开期间产生的写命令，以减少数据同步的开销

**2. 复制过程详解**

​	**2.1 建立连接与请求同步**

​	从节点启动后，会根据配置文件中的 `slaveof <master_ip> <master_port>` 命令，向主节点发起连接。一旦连接建	立，从节点会发送 `PSYNC ? -1` 命令，表明它希望进行同步，并请求主节点的复制ID和复制偏移量

​	**2.2 全量复制**

​	全量复制是数据同步的“大动作”，通常发生在以下情况：

- 从节点首次连接主节点
- 主从连接断开时间过长，无法进行增量复制

​	这个过程主要分为以下几个步骤：

1. **主节点执行 `BGSAVE`**：主节点会创建一个子进程，将当前内存中的所有数据快照保存到一个 **RDB 文件**中。这个过程是**非阻塞**的，主节点仍然可以继续处理客户端的请求
2. **主节点发送 RDB 文件**：一旦 RDB 文件生成完毕，主节点会将其通过网络发送给从节点
3. **主节点缓存新命令**：在 RDB 文件生成和传输期间，主节点会将所有新产生的写命令缓存在一个**复制积压缓冲区**中
4. **从节点清空并加载数据**：从节点接收到 RDB 文件后，会先清空自身所有旧数据，然后加载 RDB 文件。加载完成后，从节点就拥有了与主节点在 RDB 生成那一刻完全一致的数据
5. **主节点发送缓存命令**：RDB 加载完成后，主节点会将之前在缓冲区中缓存的所有新命令发送给从节点，从节点接收并执行这些命令，从而实现最终的数据同步

​	**2.3 增量复制**

​	为了避免每次短暂的网络中断都触发耗时的全量复制，Redis 2.8 及以上版本引入了增量复制。它的核心在于：

- **复制偏移量**：主从节点都会维护一个偏移量，记录已经同步了多少字节的数据
- **复制积压缓冲区**：主节点会维护一个固定大小的循环缓冲区。所有新的写命令都会被写入这个缓冲区

​	当主从连接断开后，从节点会记住自己的复制偏移量。重新连接时，它会发送 `PSYNC <master_replid> <offset>` 	命令，请求从指定偏移量开始同步

​	主节点收到请求后，会检查从节点请求的偏移量是否还在自己的复制积压缓冲区中：

- **如果在**：说明缓冲区里有从节点需要的数据。主节点会从缓冲区中找到对应的数据，并发送给从节点，从而快速完成同步
- **如果不在**：说明连接中断时间太长，缓冲区中的旧数据已经被新数据覆盖了。此时，主节点会强制执行**全量复制**

**3. Redis 主从复制的优缺点**

**优点**

- **读写分离**：可以将大量的读请求分发到从节点，减轻主节点的压力，提高系统的并发处理能力
- **数据备份**：从节点作为主节点的数据热备，可以在主节点故障时提供数据保障
- **高可用性**：配合哨兵（Sentinel）或集群（Cluster）模式，可以实现故障自动转移，保证服务的高可用

**缺点**

- **异步复制**：主从复制是异步的，主节点将数据同步给从节点是有一个延时的。如果主节点在同步完成前发生故障，可能会造成少量数据丢失
- **配置复杂性**：需要额外的服务器资源来部署从节点，并且需要进行维护和监控，增加了系统的复杂性