摘要:本文介绍了Redis的主从复制。
环境
Windows 10 企业版 LTSC 21H2
Redis 7.4.8
1 概述
主从复制是Redis的一种高可用方案,它允许将一个主节点的数据复制到多个从节点。主节点负责处理写操作,从节点负责处理读操作,从而实现读写分离,提高系统的性能和可用性。
2 作用
主从复制的作用:
- 数据备份:从节点是主节点的备份,可以防止数据丢失。
- 读写分离:主节点处理写操作,从节点处理读操作,提高系统的并发处理能力。
- 负载均衡:多个从节点可以分担读操作的压力,提高系统的整体性能。
- 高可用:当主节点发生故障时,可以将从节点升级为主节点,保证系统的可用性。
3 原理
3.1 同步过程
建立连接,在同步前需要建立主从关系:
- 从节点通过
REPLICAOF命令连接到主节点。 - 主节点进行连接验证,确认从节点的权限。
全量复制,首次同步全量命令:
- 从节点向主节点发送
PSYNC ? -1命令,表示没有主节点运行ID和从节点偏移量,请求进行全量复制。 - 主节点收到连接请求后,返回
+FULLRESYNC告知从节点进行全量复制,并且返回主节点运行ID和主节点偏移量,用于后续的同步操作。 - 主节点执行
BGSAVE命令生成RDB文件,然后将RDB文件发送给从节点。 - 从节点接收RDB文件,清空数据,执行命令,记录主节点运行ID,覆盖从节点偏移量。
- 主节点将处理RDB文件的过程中执行的命令写入积压缓冲区,将要发送的命令写入复制缓冲区并发送给从节点。
- 从节点接收复制缓冲区中的命令,执行命令。
命令传播,持续同步新增命令:
- 主节点将后续执行的命令写入积压缓冲区,将要发送的命令写入复制缓冲区并发送给从节点。
- 从节点接收复制缓冲区中的命令,执行命令。
增量复制,网络重连后同步增量命令:
- 从节点向主节点发送
PSYNC 主节点运行ID 从节点偏移量命令,表示已有主节点运行ID和从节点偏移量,请求进行增量复制。 - 主节点收到连接请求后,返回
+CONTINUE告知从节点进行增量复制。 - 主节点根据主节点偏移量和从节点偏移量,在积压缓冲区找到对应的命令,将要发送的命令写入复制缓冲区并发送给从节点。
- 从节点接收复制缓冲区中的命令,执行命令。
3.2 同步方式
3.2.1 首次同步
从节点首次同步时,没有主节点运行ID和从节点偏移量,发送PSYNC ? -1命令,主节点进行全量复制。
3.2.2 断开重连
从节点与主节点断开连接后重新连接时,已有主节点运行ID和从节点偏移量,发送PSYNC 主节点运行ID 从节点偏移量命令,主节点根据参数判断进行增量复制还是全量复制。
判断逻辑:
- 如果主节点运行ID和当前主节点运行ID相同,说明主节点未被更换,需要进行增量复制,否则进行全量复制。
- 如果从节点偏移量在积压缓冲区范围内,说明从节点存在记录,需要进行增量复制,否则进行全量复制。
3.3 缓冲处理
3.3.1 积压缓冲区
积压缓冲区属于环形缓冲区,是主节点上的唯一缓冲区,用于存储主节点最近执行的命令。
积压缓冲区溢出时会覆盖旧的命令。
3.3.2 复制缓冲区
复制缓冲区属于链式缓冲区,是主节点上的从节点专属缓冲区,用于存储从节点需要执行的命令。
复制缓冲区溢出时会自动断开从节点的连接,释放缓冲区空间。
3.3.3 共享缓冲区
由于主节点需要对每个从节点创建各自的复制缓冲区,会造成内存浪费。
为了解决这个问题,从7.0版本开始引入共享缓冲区的概念。
共享缓冲区属于链式缓冲区,用于存储主节点最近执行的命令。
共享缓冲区在内存中分成了多个数据块,每个数据块都有一个引用计数,用于记录有多少个从节点正在使用该数据块,系统会定期释放未被使用的数据块。
改变说明:
- 共享缓冲区:存储真实数据,头部用于保留历史数据块,中部用于释放未被使用的数据块,尾部的用于追加新的数据块。
- 积压缓冲区:不再存储真实数据,而是存储共享缓冲区的指针,用于在从节点断开重连时判断是否执行增量同步。
- 复制缓冲区:不再存储真实数据,而是存储共享缓冲区的指针,用于在从节点读取命令时判断是否执行命令。
3.4 触发逻辑
触发全量复制的情况:
- 从节点首次同步时,发送
PSYNC命令,主节点运行ID和从节点偏移量不存在。 - 从节点断开重连时,发送
PSYNC命令,主节点运行ID和当前主节点运行ID不相同。 - 从节点断开重连时,发送
PSYNC命令,从节点偏移量不在积压缓冲区范围内。
触发增量复制的情况:
- 从节点断开重连时,发送
PSYNC命令,主节点运行ID和当前主节点运行ID相同,并且从节点偏移量在积压缓冲区范围内。
4 配置
4.1 动态配置
在从节点上配置主节点:
1 | REPLICAOF 主节点IP地址 主节点端口号 |
从节点取消主从关系:
1 | REPLICAOF NO ONE |
4.2 配置文件
修改从节点的redis.conf配置文件。
配置主节点:
1 | # 配置主节点 |
5 状态监控
使用命令查看节点状态:
1 | INFO replication |
主节点显示结果:
# Replication:复制状态role:master:节点角色,master表示主节点connected_slaves:1:已连接的从节点数量slave0:ip=127.0.0.1,port=6381,state=online,offset=728,lag=1:从节点:IP地址、端口号、状态、复制偏移量、复制延迟,单位是秒master_failover_state:no-failover:故障转移状态,no-failover表示未发生故障转移master_replid:805f3a2e734fooc7bf4e5103a5867189c695d2c2:主节点的复制ID,建立主从关系后生成新的IDmaster_replid2:0000000000000000000000000000000000000000:发生故障转移时,原主节点的复制IDmaster_repl_offset:728:主节点的复制偏移量second_repl_offset:-1:发生故障转移时,原主节点的复制偏移量repl_backlog_active:1:是否激活积压缓冲区,1表示已激活repl_backlog_size:1048576:积压缓冲区大小repl_backlog_first_byte_offset:1:积压缓冲区中第一个字节对应的复制偏移量repl_backlog_histlen:728:积压缓冲区中实际存储的有效数据量,单位是字节
从节点显示结果:
# Replication:复制状态role:slave:节点角色,slave表示从节点master_host:127.0.0.1:主节点的IP地址master_port:6379:主节点的端口号master_link_status:up:主从连接状态,up表示正常master_last_io_seconds_ago:1:上次与主节点通信的时间,单位是秒master_sync_in_progress:0:是否正在同步数据,0表示空闲slave_read_repl_offset:728:从节点已接收的复制偏移量slave_repl_offset:728:从节点已执行的复制偏移量slave_priority:100:从节点的优先级slave_read_only:1:从节点是否只读,1表示只读replica_announced:1:从节点是否显示,1表示显示connected_slaves:0:已连接的从节点数量master_failover_state:no-failover:故障转移状态,no-failover表示未发生故障转移master_replid:805f3a2e734fooc7bf4e5103a5867189c695d2c2:主节点的复制ID,建立主从关系后生成新的IDmaster_replid2:0000000000000000000000000000000000000000:发生故障转移时,原主节点的复制IDmaster_repl_offset:728:主节点的复制偏移量second_repl_offset:-1:发生故障转移时,原主节点的复制偏移量repl_backlog_active:1:是否激活积压缓冲区,1表示已激活repl_backlog_size:1048576:积压缓冲区大小repl_backlog_first_byte_offset:15:积压缓冲区中第一个字节对应的复制偏移量repl_backlog_histlen:714:积压缓冲区中实际存储的有效数据量,单位是字节
6 最佳实践
对于生产环境,建议使用哨兵模式,实现主节点的自动故障转移。
条