Redis 主从复制
1. 主从复制简介
Redis 主从复制是指将一台 Redis 服务器的数据复制到其他 Redis 服务器。前者称为主节点(Master),后者称为从节点(Slave)。数据的复制是单向的,只能由主节点到从节点。
主从复制的主要作用:
- 数据冗余:实现了数据的热备份,是持久化之外的一种数据冗余方式
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载
- 高可用基石:主从复制是哨兵模式和集群模式能够实施的基础
1.1 主从复制架构图
+----------------+
| 主节点 |
| (Master) |
+----------------+
|
| 复制
↓
+----------------+----------------+
↓ ↓ ↓
+----------------+ +----------------+ +----------------+
| 从节点1 | | 从节点2 | | 从节点3 |
| (Slave) | | (Slave) | | (Slave) |
+----------------+ +----------------+ +----------------+
2. 主从复制原理
2.1 复制过程
Redis 主从复制的过程主要分为三个阶段:
建立连接阶段:
- 从节点执行 SLAVEOF 命令,向主节点发送连接请求
- 主节点接受连接,建立与从节点的连接
- 从节点保存主节点的信息(IP 和端口)
示例命令:
# 在从节点上执行 127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 OK数据同步阶段:
- 主节点执行 BGSAVE 命令,生成 RDB 文件
- 主节点将 RDB 文件发送给从节点
- 从节点清空自身数据,加载 RDB 文件
- 主节点将缓冲区中的写命令发送给从节点
同步过程示例:
# 主节点日志 1:M 20 Mar 10:00:00.000 * Slave 127.0.0.1:6380 asks for synchronization 1:M 20 Mar 10:00:00.001 * Starting BGSAVE for SYNC with target: disk 1:M 20 Mar 10:00:00.002 * Background saving started by pid 1234命令传播阶段:
- 主节点将写命令发送给从节点
- 从节点接收并执行命令,保持与主节点的数据一致性
2.2 复制机制
Redis 主从复制采用异步复制机制,具有以下特点:
- 主节点可以同时复制给多个从节点
- 从节点可以接收来自主节点的数据
- 复制过程不会阻塞主节点
- 从节点可以配置为只读模式
复制状态查看命令:
# 查看主节点复制信息
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1234,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=1234,lag=0
3. 主从复制配置
3.1 主节点配置
主节点无需特殊配置,保持默认配置即可:
# redis.conf
port 6379
bind 127.0.0.1
daemonize yes
# 设置主节点密码(可选)
requirepass yourpassword
3.2 从节点配置
从节点需要配置主节点的信息:
# redis.conf
port 6380
bind 127.0.0.1
daemonize yes
slaveof 127.0.0.1 6379
# 如果主节点设置了密码,需要配置
masterauth yourpassword
# 设置从节点只读
slave-read-only yes
或者通过命令配置:
# 设置主节点
SLAVEOF 127.0.0.1 6379
# 设置主节点密码
CONFIG SET masterauth yourpassword
4. 主从复制优化
4.1 复制缓冲区
复制缓冲区用于存储主节点最近执行的写命令,配置项:
# redis.conf
# 设置复制缓冲区大小,建议设置为内存的 1/10
repl-backlog-size 1gb
# 设置复制缓冲区过期时间
repl-backlog-ttl 3600
4.2 复制超时
设置复制超时时间,避免网络问题导致复制中断:
# redis.conf
# 复制超时时间,单位秒
repl-timeout 60
# 复制延迟检查时间
repl-ping-slave-period 10
4.3 延迟复制
配置从节点延迟复制,避免主节点故障导致数据丢失:
# redis.conf
# 启用延迟复制
replica-lazy-flush yes
# 设置延迟复制时间
replica-lazy-flush-delay 1000
5. 主从复制问题
5.1 数据一致性问题
5.1.1 异步复制导致的数据不一致
问题描述: Redis 主从复制采用异步复制机制,主节点执行写命令后立即返回,不等待从节点确认。这可能导致:
- 主节点写入成功,但从节点还未同步
- 客户端从从节点读取到过期数据
- 主节点故障时,从节点可能丢失部分数据
解决方案:
# 1. 使用WAIT命令等待指定数量的从节点确认
127.0.0.1:6379> SET key value
OK
127.0.0.1:6379> WAIT 1 1000 # 等待1个从节点确认,超时时间1000ms
(integer) 1
# 2. 配置min-replicas-to-write确保至少N个从节点在线
CONFIG SET min-replicas-to-write 1
CONFIG SET min-replicas-max-lag 10
5.1.2 网络分区导致的数据不一致
问题描述: 网络分区可能导致:
- 主从节点无法通信
- 从节点认为主节点故障,可能提升自己为主节点
- 出现脑裂现象,多个主节点同时存在
解决方案:
# 配置主节点最小从节点数量
min-replicas-to-write 1
min-replicas-max-lag 10
# 配置从节点超时时间
repl-timeout 60
repl-ping-slave-period 10
5.2 性能问题
5.2.1 全量同步性能问题
问题描述:
- 从节点首次连接或长时间断开后重连时,需要进行全量同步
- 全量同步会生成 RDB 文件,消耗大量 CPU 和内存
- 大文件传输占用网络带宽,影响其他操作
解决方案:
# 1. 优化RDB生成配置
save 900 1
save 300 10
save 60 10000
# 2. 使用无盘复制(Redis 2.8.18+)
repl-diskless-sync yes
repl-diskless-sync-delay 5
# 3. 调整复制缓冲区大小
repl-backlog-size 1gb
repl-backlog-ttl 3600
5.2.2 复制延迟问题
问题描述:
- 从节点复制延迟过高
- 影响读写分离场景下的数据一致性
- 可能导致从节点数据过期
解决方案:
# 1. 监控复制延迟
127.0.0.1:6379> INFO replication
# 查看lag字段,表示复制延迟(秒)
# 2. 优化网络配置
tcp-keepalive 60
tcp-nodelay yes
# 3. 调整复制相关参数
repl-ping-slave-period 10
repl-timeout 60
5.3 内存问题
5.3.1 复制缓冲区内存占用
问题描述:
- 复制缓冲区占用大量内存
- 多个从节点时,每个从节点都需要独立的复制缓冲区
- 可能导致内存不足
解决方案:
# 1. 合理设置复制缓冲区大小
repl-backlog-size 1gb # 根据内存情况调整
# 2. 设置复制缓冲区过期时间
repl-backlog-ttl 3600
# 3. 监控内存使用情况
127.0.0.1:6379> INFO memory
5.3.2 从节点内存同步问题
问题描述:
- 从节点在同步过程中需要额外内存存储 RDB 数据
- 可能导致从节点内存不足
- 影响从节点的正常服务
解决方案:
# 1. 使用无盘复制减少内存占用
repl-diskless-sync yes
# 2. 配置从节点内存策略
maxmemory-policy allkeys-lru
# 3. 监控从节点内存使用
127.0.0.1:6380> INFO memory
5.4 网络问题
5.4.1 网络中断导致复制失败
问题描述:
- 网络不稳定导致主从连接中断
- 从节点频繁重连,影响性能
- 可能导致数据丢失
解决方案:
# 1. 配置重连参数
repl-timeout 60
repl-ping-slave-period 10
# 2. 启用TCP keepalive
tcp-keepalive 60
# 3. 配置网络优化
tcp-nodelay yes
5.4.2 跨机房复制问题
问题描述:
- 跨机房网络延迟高
- 网络不稳定,容易中断
- 数据同步延迟大
解决方案:
# 1. 调整超时参数
repl-timeout 120
repl-ping-slave-period 30
# 2. 使用压缩传输
repl-diskless-sync yes
# 3. 考虑使用Redis Cluster或哨兵模式
5.5 故障恢复问题
5.5.1 主节点故障处理
问题描述:
- 主节点故障后,从节点无法自动提升为主节点
- 需要手动干预进行故障转移
- 服务中断时间较长
解决方案:
# 1. 使用Redis Sentinel实现自动故障转移
# 2. 配置从节点提升为主节点
SLAVEOF NO ONE
# 3. 更新其他从节点的主节点配置
SLAVEOF new-master-ip new-master-port
5.5.2 从节点故障恢复
问题描述:
- 从节点故障后重新启动
- 需要重新同步数据
- 可能影响主节点性能
解决方案:
# 1. 配置从节点自动重连
slaveof 127.0.0.1 6379
# 2. 使用增量同步减少同步时间
# 3. 监控从节点状态
127.0.0.1:6379> INFO replication
5.6 配置问题
5.6.1 密码认证问题
问题描述:
- 主从节点密码不匹配
- 认证失败导致复制中断
- 安全配置不当
解决方案:
# 1. 主节点配置密码
requirepass yourpassword
# 2. 从节点配置主节点密码
masterauth yourpassword
# 3. 验证认证配置
127.0.0.1:6380> AUTH yourpassword
5.6.2 端口和绑定地址问题
问题描述:
- 端口冲突
- 绑定地址配置错误
- 防火墙阻止连接
解决方案:
# 1. 检查端口配置
port 6379
bind 0.0.0.0 # 或指定具体IP
# 2. 检查防火墙设置
# 3. 验证网络连通性
telnet master-ip master-port
5.7 监控和诊断
5.7.1 复制状态监控
监控命令:
# 查看复制信息
127.0.0.1:6379> INFO replication
# 查看从节点列表
127.0.0.1:6379> CLIENT LIST
# 查看复制偏移量
127.0.0.1:6379> ROLE
5.7.2 常见问题诊断
诊断步骤:
- 检查网络连通性
- 验证配置参数
- 查看日志文件
- 监控复制延迟
- 检查内存使用情况
日志示例:
# 主节点日志
1:M 20 Mar 10:00:00.000 * Slave 127.0.0.1:6380 asks for synchronization
1:M 20 Mar 10:00:00.001 * Starting BGSAVE for SYNC with target: disk
1:M 20 Mar 10:00:00.002 * Background saving started by pid 1234
# 从节点日志
1:S 20 Mar 10:00:00.000 * Connecting to MASTER 127.0.0.1:6379
1:S 20 Mar 10:00:00.001 * MASTER <-> REPLICA sync started
1:S 20 Mar 10:00:00.002 * Non blocking connect for SYNC fired the event
5.8 最佳实践
5.8.1 生产环境建议
- 使用 Redis Sentinel 或 Cluster 模式:避免手动故障转移
- 合理配置复制参数:根据网络环境调整超时和缓冲区大小
- 监控复制状态:及时发现和处理问题
- 定期备份:除了复制外,定期进行数据备份
- 网络优化:使用专用网络,避免跨机房复制
5.8.2 性能优化建议
- 调整复制缓冲区大小:根据内存情况合理设置
- 使用无盘复制:减少磁盘 I/O,提高同步速度
- 优化网络配置:启用 TCP_NODELAY,调整 keepalive 参数
- 监控复制延迟:及时发现性能问题
- 合理规划从节点数量:避免过多从节点影响主节点性能
