主从架构
- 主从架构
-
- 什么是主从架构
- 复制机制的工作原理
-
- [1. 全量复制(Full Synchronization)](#1. 全量复制(Full Synchronization))
- [2. 部分复制(Partial Synchronization)](#2. 部分复制(Partial Synchronization))
- [3. PSYNC2机制(Redis 4.0+)](#3. PSYNC2机制(Redis 4.0+))
- 主从架构的关键技术细节
-
- [1. 复制积压缓冲区(Replication Backlog)](#1. 复制积压缓冲区(Replication Backlog))
- [2. 复制偏移量(Replication Offset)](#2. 复制偏移量(Replication Offset))
- [3. 主节点ID(Run ID)](#3. 主节点ID(Run ID))
- 什么是PSYNC2
- 主从模式有什么缺点
主从架构
什么是主从架构
Redis主从架构(Master-Slave Architecture)本质上是一种数据复制模型,它通过将数据从主节点复制到一个或多个从节点,实现数据冗余、负载分担和高可用性。
基本架构
+-------------+
| Master |
| (写操作) |
+------+------+
|
| 数据复制
|
+------v------+ +-------------+ +-------------+
| Slave 1 |---->| Slave 2 |---->| Slave 3 |
| (只读) | | (只读) | | (只读) |
+-------------+ +-------------+ +-------------+
在这种结构中有三个角色:
- 主节点(Master):接收写操作,执行数据变更
- 从节点(Slave):从主节点复制数据,提供读服务
- 复制流:数据变更从主节点流向从节点
复制机制的工作原理
Redis主从复制经历了三代演进,分别是SYNC机制、PSYNC机制和PSYNC2机制,每一代都解决了前一代的关键问题:
1. 全量复制(Full Synchronization)
当从节点首次连接主节点或复制出现问题需要重新同步时,会触发全量复制:
+--------+ +--------+
| Master | | Slave |
+----+---+ +---+----+
| |
| PSYNC/SYNC |
|<--------------------------|
| |
| FULLRESYNC |
|------------------------->|
| |
| RDB文件传输 |
|------------------------->|
| |
具体步骤:
- 从节点发送PSYNC/SYNC命令
- 主节点执行BGSAVE生成RDB文件
- 主节点将RDB文件发送给从节点
- 从节点清空自身数据,加载RDB文件
- 主节点将缓冲区中的写命令发送给从节点
- 开始持续复制过程
其主要缺点是网络中断后必须重新全量同步,对于大型数据集效率极低。
我曾在一个16GB的Redis实例上测试,全量同步需要约12分钟,期间系统负载增加300%。
2. 部分复制(Partial Synchronization)
部分复制,用于处理短暂网络中断后的恢复:
+--------+ +--------+
| Master | | Slave |
+----+---+ +---+----+
| |
| PSYNC <runid> <offset>
|<--------------------------|
| |
| CONTINUE |
|------------------------->|
| |
| 部分命令传输 |
|------------------------->|
| |
工作原理:
- 主节点维护一个复制积压缓冲区(replication backlog)
- 从节点断开重连后,发送PSYNC命令,包含主节点ID和复制偏移量
- 如果偏移量在积压缓冲区范围内,主节点回复CONTINUE
- 然后主节点只发送从节点缺失的部分数据
这大大减少了短暂网络中断导致的全量同步,但在复杂拓扑结构下仍有局限。
3. PSYNC2机制(Redis 4.0+)
Redis 4.0引入的增强版部分复制,支持更灵活的复制拓扑:
+--------+ +--------+ +--------+
| Master |---->| Slave1 |---->| Slave2 |
+--------+ +--------+ +--------+
核心改进在于:
- 引入复制ID和复制历史记录,支持复杂拓扑下的部分复制
- 支持级联复制中任意节点断开后的部分同步
- 优化了复制协议效率,减少了约40%的网络传输
- 支持在主从切换等拓扑变更场景下的部分同步
之前测试全量同步,后面升级到PSYNC2后,主从切换时间从15分钟减少到了2分钟,很夸张的提升了.
这三代复制机制的演进体现了Redis在保持简单性的同时不断提升复制效率和可靠性的设计哲学。"
主从架构的关键技术细节
1. 复制积压缓冲区(Replication Backlog)
+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ... 命令序列
+---+---+---+---+---+---+---+---+
^ ^
| |
tail head
"复制积压缓冲区(replication backlog)是Redis部分复制的核心机制,它本质上是一个固定大小的环形缓冲区(ring buffer),由主节点维护。
- 环形缓冲区,默认大小1MB(可配置)
- 存储最近执行的写命令
- 用于支持部分复制
- 配置参数:
repl-backlog-size
工作原理:
- 主节点将每个写命令同时写入复制积压缓冲区和从节点
- 缓冲区以偏移量(offset)标记每个命令的位置
- 从节点断开重连后,发送自身的复制偏移量
- 主节点检查该偏移量是否在缓冲区范围内:
- 如果在范围内,执行部分复制(CONTINUE)
- 如果不在范围内,执行全量复制(FULLRESYNC)
复制积压缓冲区的合理配置是Redis主从架构稳定性的关键因素之一,值得投入时间进行精细调优。
复制积压缓冲区大小应该至少能容纳从节点可能断开的最长时间内产生的所有写命令。计算公式为:
repl-backlog-size = 写入速率(bytes/s) × 预期最大断开时间(s) × 安全系数(1.5-2)
原本设置的1MB默认值导致频繁全量同步。通过监控发现:
- 平均写入速率:2MB/秒
- 网络偶发中断:最长90秒
计算得出理想大小:2MB/s × 90s × 2 = 360MB
将参数调整为512MB后,全量同步次数从每天20-30次降至每月1-2次,系统稳定性显著提升。
2. 复制偏移量(Replication Offset)
- 主节点和从节点各自维护一个复制偏移量
- 表示复制的进度位置
- 用于检测复制是否一致
- 可通过INFO replication命令查看
3. 主节点ID(Run ID)
- 每个Redis实例启动时生成的40字节随机ID
- 用于标识复制关系中的主节点
- 从节点通过ID判断是否与之前连接的是同一主节点
什么是PSYNC2
"PSYNC2是Redis 4.0引入的增强版部分复制机制,主要解决了复杂拓扑结构下的复制效率和稳定性问题。"
核心问题
"它主要解决了三个核心问题:
首先,解决了级联复制中的'多米诺骨牌'效应。在旧版本中,如果中间从节点断开重连,会导致整个复制链上的所有下游从节点都需要全量同步,消耗大量资源。
其次,优化了复制拓扑变更场景。以前主从切换后,从节点总是需要全量同步,即使数据差异很小。
第三,提高了复制协议效率,改进了复制状态识别机制,使复制过程更加稳定和高效。"
技术实现要点
"PSYNC2通过几个关键技术实现这些改进:
- 引入了复制ID和复制历史记录,使从节点能够更准确地判断是否可以进行部分同步。
- 增强了复制状态跟踪机制,支持在复杂网络环境下的状态恢复。
- 优化了复制协议,减少了传输开销,提高了复制效率。"
实际价值
"在实际应用中,PSYNC2显著提高了Redis集群的稳定性和性能。例如,在我负责的一个项目中,主从切换时间从原来的15分钟减少到了不到2分钟,系统可用性得到了极大提升。"
总结
"总之,PSYNC2是Redis复制机制的重要进步,为构建大规模、高可用的Redis集群提供了更坚实的基础。"
PSYNC2机制的局限性
- 首先,它仍然依赖复制积压缓冲区,如果网络中断时间过长超出缓冲区容量,依然会触发全量同步。
- 其次维护复制历史记录需要额外内存资源,在资源受限环境中需要权衡。在极端情况下,如果主节点频繁切换,从节点可能需要频繁重建复制历史,这会增加主节点的负担。
主从模式有什么缺点
主要缺点有:
- 高可用问题:主从架构存在单点故障风险。主节点宕机会导致写服务完全不可用,且没有自动故障转移机制,需要人工干预
- 数据一致性问题:由于Redis采用异步复制机制,存在数据丢失风险。主节点崩溃时,已接收但未同步到从节点的数据会永久丢失。
- 写性能问题:主节点写入压力大时,从节点可能出现延迟,影响读服务性能。
优点: - 成本低:使用普通服务器即可搭建主从架构,成本较低。
- 简单易用:配置和管理相对简单,适合中小规模应用。
- 读性能提升:主节点负责写入,从节点负责读取,可以显著提升读服务性能。