Redis 主从复制详解
·
Redis 主从复制详解
📅 创建时间:2026-02-25
🏷️ 标签:#redis #主从复制 #高可用
一、什么是 Redis 主从复制
Redis 主从复制(Master-Slave Replication)是指将一台 Redis 服务器(主节点 Master)的数据,同步到其他一台或多台 Redis 服务器(从节点 Slave)的机制。

二、核心特点
1. 数据流向
- 单向同步:只能从 Master 同步到 Slave,不能反向
- 级联复制:Slave 也可以有自己的 Slave,形成级联结构
2. 读写分离
- Master:负责写操作(也可读)
- Slave:只负责读操作,不能写
3. 数据一致性
- 最终一致性:Slave 数据会延迟于 Master
- 异步复制:Master 不需等待 Slave 完成同步
三、主要作用与优势
✅ 1. 数据冗余备份
- 提供数据的热备份,提高数据安全性
- 当 Master 故障时,有完整的数据副本
✅ 2. 读写分离,性能提升
- Master 负责写操作,分担写压力
- 多个 Slave 负责读操作,提升读并发能力
- 适合读多写少的业务场景
✅ 3. 高可用基础
- 是 Redis Sentinel(哨兵)和 Redis Cluster(集群)的基础
- 故障恢复:可以快速将从节点提升为主节点
✅ 4. 负载均衡
- 多个从节点分担读请求
- 可根据业务需求配置不同地理位置的从节点
四、工作原理
复制流程(全量复制 + 增量复制)

详细步骤:
1. 连接建立阶段
- Slave 启动后,连接到 Master
- 发送
PSYNC命令请求同步
2. 全量同步阶段(初次)
- Master 执行
BGSAVE生成 RDB 快照 - Master 将 RDB 文件发送给 Slave
- Slave 接收并加载 RDB 文件
- Master 将期间的写命令缓存并发送
3. 增量同步阶段(正常运行)
- Master 每执行一个写命令,就发送给所有 Slave
- Slave 执行接收到的命令,保持数据一致
4. 心跳检测
- Slave 定期发送
REPLCONF ACK报告复制进度 - 检测网络连接状态
复制偏移量(Replication Offset)
- Master 和 Slave 都维护一个复制偏移量
- 表示当前复制的数据位置
- 用于判断数据同步的状态和进度
Master: offset = 1000
│ 写入了 10 字节数据
▼
Master: offset = 1010 ── 发送命令 ──> Slave: offset = 1010
五、配置方法
1. 临时配置(命令行)
在 Slave 节点上执行:
# 连接到 Redis Slave
redis-cli -h slave_host -p 6379
# 设置主节点信息
SLAVEOF master_host master_port
# 如果 Master 设置了密码
CONFIG SET masterauth <password>
# 查看复制状态
INFO replication
2. 永久配置(配置文件)
在 Slave 的 redis.conf 文件中添加:
# 指定 Master 的 IP 和端口
slaveof master_host master_port
# 如果 Master 设置了密码
masterauth <master-password>
# 从节点只读(默认开启)
slave-read-only yes
# 从节点优先级(越小越优先被提升为主节点)
slave-priority 100
# 最小从节点连接数(新特性,用于保障数据安全)
min-slaves-to-write 1
min-slaves-max-lag 10
3. Docker 配置示例
# docker-compose.yml
version: '3'
services:
redis-master:
image: redis:7.0
container_name: redis-master
ports:
- "6379:6379"
command: redis-server --requirepass master123
redis-slave1:
image: redis:7.0
container_name: redis-slave1
ports:
- "6380:6379"
command: redis-server --slaveof redis-master 6379 --masterauth master123 --requirepass slave123
depends_on:
- redis-master
redis-slave2:
image: redis:7.0
container_name: redis-slave2
ports:
- "6381:6379"
command: redis-server --slaveof redis-master 6379 --masterauth master123 --requirepass slave123
depends_on:
- redis-master
六、关键配置参数详解
主节点相关参数
# 设置密码(同时影响主从复制)
requirepass <password>
# 允许写入的最少从节点数(保障数据安全)
min-slaves-to-write 1
# 从节点最大延迟(秒)
min-slaves-max-lag 10
从节点相关参数
# 指定主节点
slaveof <masterip> <masterport>
# 主节点密码
masterauth <master-password>
# 从节点只读
slave-read-only yes
# 从节点优先级(越小越优先)
slave-priority 100
# 从节点断开连接后是否继续服务旧数据
slave-serve-stale-data yes
# 从节点是否开启 TCP_NODELAY(减少延迟)
repl-disable-tcp-nodelay no
网络相关参数
# 复制积压缓冲区大小(用于增量同步)
repl-backlog-size 1mb
# 复制积压缓冲区保留时间
repl-backlog-ttl 3600
# 主从节点心跳间隔(秒)
repl-ping-slave-period 10
# 从节点超时时间(秒)
repl-timeout 60
七、监控与管理
1. 查看复制状态
# 在 Master 上执行
127.0.0.1:6379> INFO replication
# Output:
# role:master
# connected_slaves:2
# slave0:ip=192.168.1.101,port=6379,state=online,offset=12345,lag=0
# slave1:ip=192.168.1.102,port=6379,state=online,offset=12345,lag=0
# 在 Slave 上执行
127.0.0.1:6379> INFO replication
# Output:
# role:slave
# master_host:192.168.1.100
# master_port:6379
# master_link_status:up
# master_last_io_seconds_ago:3
# master_sync_in_progress:0
# slave_repl_offset:12345
2. 关键监控指标
| 指标 | 说明 | 健康值 |
|---|---|---|
master_link_status |
主从连接状态 | up |
master_last_io_seconds_ago |
最后一次通信时间 | < 10秒 |
slave_repl_offset |
复制偏移量 | 与 Master 接近 |
master_sync_in_progress |
是否正在同步 | 0(空闲) |
connected_slaves |
Master 连接的从节点数 | >= 2(生产环境) |
3. 监控脚本示例
#!/bin/bash
# monitor_redis_replication.sh
MASTER_HOST="192.168.1.100"
MASTER_PORT="6379"
echo "=== Redis Replication Status ==="
echo "Time: $(date)"
# 检查 Master
MASTER_INFO=$(redis-cli -h $MASTER_HOST -p $MASTER_PORT INFO replication)
SLAVE_COUNT=$(echo "$MASTER_INFO" | grep "connected_slaves" | cut -d: -f2)
echo "Master: $MASTER_HOST:$MASTER_PORT"
echo "Connected Slaves: $SLAVE_COUNT"
# 检查每个 Slave
echo "$MASTER_INFO" | grep "slave" | while read line; do
IP=$(echo $line | cut -d: -f2 | cut -d, -f1 | cut -d= -f2)
PORT=$(echo $line | cut -d: -f2 | cut -d, -f2 | cut -d= -f2)
STATE=$(echo $line | cut -d: -f2 | cut -d, -f3 | cut -d= -f2)
LAG=$(echo $line | cut -d: -f2 | cut -d, -f5 | cut -d= -f2)
echo " - Slave: $IP:$PORT, State: $STATE, Lag: ${LAG}s"
if [ "$STATE" != "online" ]; then
echo " ⚠️ WARNING: Slave is not online!"
fi
if [ "$LAG" -gt 10 ]; then
echo " ⚠️ WARNING: Replication lag is too high!"
fi
done
echo "================================"
八、常见问题与故障处理
❌ 问题 1:从节点无法连接主节点
现象:master_link_status: down
排查步骤:
- 检查网络连通性:
ping master_host - 检查端口是否开放:
telnet master_host master_port - 检查 Master 密码是否正确:
masterauth配置 - 检查防火墙设置
- 查看 Redis 日志:
tail -f /var/log/redis/redis-server.log
解决方案:
# 重新配置主节点
redis-cli SLAVEOF NO ONE # 先断开
redis-cli SLAVEOF master_host master_port # 再重新连接
❌ 问题 2:复制延迟过高
现象:master_last_io_seconds_ago > 30秒 或 lag 值很大
原因:
- 网络带宽不足
- Master 写入量过大
- Slave 性能不足(CPU/内存)
- 存在慢查询阻塞
解决方案:
- 优化网络环境
- 增加 Slave 节点分担读压力
- 升级 Slave 硬件配置
- 优化 Redis 配置:
repl-disable-tcp-nodelay no - 监控慢查询:
SLOWLOG GET 10
❌ 问题 3:全量同步频繁
现象:日志中频繁出现 Full resync
原因:
- 复制积压缓冲区
repl-backlog-size太小 - 网络不稳定导致连接断开
- Slave 重启或网络中断时间过长
解决方案:
# 增加复制积压缓冲区
repl-backlog-size 256mb
# 增加缓冲区保留时间
repl-backlog-ttl 7200
❌ 问题 4:复制中断后无法恢复
现象:Slave 断开连接后无法自动重连
原因:
- Master 的
maxmemory配置导致写操作失败 - 客户端输出缓冲区溢出
解决方案:
# 增加客户端输出缓冲区限制
client-output-buffer-limit slave 256mb 64mb 60
# 确保 Master 有足够的内存
maxmemory-policy allkeys-lru # 或其他合适的淘汰策略
九、架构注意事项
📌 1. 数据一致性
- 异步复制:Master 不等待 Slave 确认,存在数据丢失风险
- 复制延迟:Slave 数据可能落后于 Master
- 解决方案:
- 对强一致性要求高的业务,读 Master
- 使用
WAIT命令等待至少 N 个 Slave 同步
📌 2. 故障恢复
# Slave 提升为 Master
docker exec -it redis-slave1 redis-cli
> SLAVEOF NO ONE
> CONFIG SET slave-read-only no
# 将其他 Slave 指向新的 Master
docker exec -it redis-slave2 redis-cli
> SLAVEOF new_master_ip new_master_port
📌 3. 读写分离实现
在应用层实现读写分离:
// Java 示例 - Spring Boot
@Configuration
public class RedisConfig {
@Bean
public LettuceConnectionFactory masterConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("master_host", 6379);
return new LettuceConnectionFactory(config);
}
@Bean
public LettuceConnectionFactory slaveConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("slave_host", 6379);
return new LettuceConnectionFactory(config);
}
@Bean(name = "masterRedisTemplate")
public RedisTemplate<String, Object> masterRedisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(masterConnectionFactory());
return template;
}
@Bean(name = "slaveRedisTemplate")
public RedisTemplate<String, Object> slaveRedisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(slaveConnectionFactory());
return template;
}
}
@Service
public class UserService {
@Autowired
@Qualifier("masterRedisTemplate")
private RedisTemplate<String, Object> masterRedisTemplate;
@Autowired
@Qualifier("slaveRedisTemplate")
private RedisTemplate<String, Object> slaveRedisTemplate;
public void saveUser(User user) {
// 写操作:使用 Master
masterRedisTemplate.opsForValue().set("user:" + user.getId(), user);
}
public User getUser(Long id) {
// 读操作:使用 Slave
return (User) slaveRedisTemplate.opsForValue().get("user:" + id);
}
}
📌 4. 生产环境建议
架构图:
┌─────────────┐
│ Load Balancer
│ (读请求分发)
└──────┬──────┘
│
┌────────┼────────┬────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Slave 1 │ │ Slave 2 │ │ Slave 3 │ │ Slave N │
│ (读) │ │ (读) │ │ (读) │ │ (读) │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│
│ 写入/复制
▼
┌─────────────┐
│ Redis Master│
│ (写) │
└─────────────┘
最佳实践:
- 至少 2 个从节点:保证高可用性
- 异地备份:将 Slave 部署在不同机房
- 监控延迟:设置告警阈值(如 lag > 10s)
- 网络质量:确保主从之间网络稳定、低延迟
- 容量规划:Slave 配置不低于 Master
- 密码认证:生产环境必须设置强密码
📌 5. 升级与维护
# 平滑升级 Slave 步骤:
1. 停止 Slave 服务
2. 备份数据
3. 升级 Redis 版本
4. 启动 Slave 服务
5. 验证复制状态
6. 重复 1-5 对其他 Slave
7. 手动故障转移(Master -> Slave)
8. 升级原 Master
# 使用 Sentinel 自动故障转移(推荐)
十、总结
主从复制适用场景
✅ 适合:
- 读多写少的业务场景
- 数据备份和容灾恢复
- 读写分离提升性能
- 构建 Redis 高可用架构
❌ 不适合:
- 频繁网络波动的环境
- 需要强一致性的场景
- 写入量远大于读取量的场景
关键配置回顾
| 配置项 | 作用 | 推荐值 |
|---|---|---|
slaveof |
指定主节点 | IP:PORT |
masterauth |
主节点密码 | 强密码 |
slave-read-only |
从节点只读 | yes |
repl-backlog-size |
复制积压缓冲区 | 256MB+ |
repl-timeout |
复制超时时间 | 60-120s |
slave-priority |
从节点优先级 | 100 |
下一步学习建议:
- 阅读 [[Redis Sentinel 哨兵机制详解]] → 实现自动故障转移
- 阅读 [[Redis Cluster 集群详解]] → 实现数据分片和水平扩展
- 实践:在本地搭建一主二从架构并测试故障转移
参考资料:
- Redis 官方文档 - Replication
- 《Redis 设计与实现》- 黄健宏
- Redis 源码:
replication.c
更多推荐




所有评论(0)