单机 Redis 挂了怎么办?数据怎么备份?这篇讲 Redis 的高可用方案:主从复制让数据有备份、读写分离,哨兵让故障自动切换,保证服务不中断。
一、为什么需要主从复制?
1.1 单机 Redis 的隐患
单机部署 Redis 有三个问题:
1.2 主从复制的思路
主从复制(Master-Slave Replication):一台主节点(Master)负责写,一台或多台从节点(Slave)负责读,数据实时同步到从节点。
写请求
↓
┌───┴───┐
│ Master │ ← 唯一能写的
└───┬───┘
复制同步 │
┌──────┴──────┐
┌──┴──┐ ┌──┴──┐
│Slave1│ │Slave2│ ← 只负责读
└─────┘ └─────┘
↑ 读请求 ↑ 读请求
主从复制解决了三个问题:
二、如何配置主从
2.1 命令行方式(临时)
从节点上用 slaveof 指定主节点:
# 在从节点上执行
SLAVEOF 192.168.1.100 6379
# 让当前节点成为 192.168.1.100:6379 的从节点
2.2 配置文件方式(推荐)
在从节点的 redis.conf 里加:
# 指定主节点地址
slaveof 192.168.1.100 6379
# 主节点有密码就配置
masterauth 123456
重启从节点即可生效。
2.3 查看复制状态
用 info replication 查看:
127.0.0.1:6379> info replication
role:master # 角色:主节点
connected_slaves:2 # 有2个从节点
三、复制原理
3.1 全量复制 vs 增量复制
主从同步分两种情况:
第一次同步(全量复制):
后续同步(增量复制):
- 主节点每次写操作,都把命令发给从节点执行
- 从节点持续跟进主节点的最新状态
3.2 断线重连
如果主从连接中断,从节点重连后,会尝试用增量复制补上断开的命令——只要命令还在复制积压缓冲区里就能补;如果断了太久缓冲区被覆盖,就退化成全量复制。
三-补充、Redis 持久化:RDB 与 AOF
主从复制的全量复制依赖 RDB,所以这里把 Redis 的持久化机制一起讲了。持久化解决的是"Redis 重启后数据不丢"的问题。
3.1 为什么需要持久化
Redis 数据在内存里,一重启就没了。但如果 Redis 挂了重启后数据全部丢失,缓存还得重新从数据库加载,高并发下瞬间压垮数据库。所以要把数据落盘。
Redis 有两种持久化方式:RDB(快照) 和 AOF(追加日志)。
3.2 RDB 快照持久化
RDB 是把某个时刻的内存数据完整保存成一个二进制文件(默认 dump.rdb)。主从全量复制传的就是这个文件。
触发方式:
- 手动 SAVE(阻塞)或 BGSAVE(后台异步)
- 配置自动触发:N秒内M次写就保存
# 60秒内有1000次写,就生成快照
save 60 1000
优点: 文件小、加载快、适合备份
缺点: 是"某个时间点的快照",两次快照之间的数据可能丢
3.3 AOF 追加持久化
AOF 是把每次写命令追加到日志文件里。重启时重放日志,恢复数据。
# 开启AOF
appendonly yes
# 写策略:always每次写都落盘 / everysec每秒落盘 / no交给系统
appendfsync everysec
优点: 数据丢失少(everysec最多丢1秒数据)
缺点: 文件大、重启加载慢
3.4 两种怎么选
| 数据完整性 | 可能丢两次快照间数据 | everysec最多丢1秒 |
| 文件大小 | 小 | 大 |
| 恢复速度 | 快 | 慢 |
| 占用CPU | 生成快照时高 | 写日志持续 |
生产实践:两个都开,RDB 做冷备,AOF 保证数据。 Redis 4.0 之后还支持 AOF 重写和混合持久化,这里不展开。
四、哨兵模式(Sentinel)
4.1 主从复制的缺点
主从复制解决了备份和读压力,但有个大问题:主节点挂了,系统就停了。
- 主节点宕机后,从节点虽然有数据,但不会自动升级为主节点
- 写请求仍然指向已宕机的主节点,服务中断,需要人工介入
4.2 哨兵是什么
哨兵(Sentinel)就是 Redis 的"监控+自动故障转移"组件。 它干三件事:
哨兵 Sentinel
│ 监控
├── 监控 Master
├── 监控 Slave1
└── 监控 Slave2
4.3 哨兵架构
实际部署时,哨兵本身也要多实例部署(一般3个或以上),避免哨兵自己也变成单点:
┌── Sentinel1
Master ← ├── Sentinel2 ← 三个哨兵互相监控,共同决策
└── Sentinel3
│
Slave1 Slave2
为什么哨兵要多数? 哨兵判断主节点是否故障,采用"主观下线 + 客观下线"机制:
- 一个哨兵发现联系不上主节点 → 主观下线(自己判断)
- 多数哨兵(超过一半)都认为主节点下线 → 客观下线(大家一致)→ 才触发故障转移
这样不会因为网络抖动一个哨兵误判就切换。
4.4 故障转移流程
1. 主节点 Master 突然宕机
2. 哨兵发现,标记主观下线
3. 多数哨兵确认 → 客观下线
4. 哨兵们选举一个 Leader 哨兵
5. Leader 哨兵从从节点里选一个(优先选数据最全、优先级最高、runid最小的)
6. 把这个从节点提升为新 Master
7. 通知其他从节点重新指向新 Master
8. 通知客户端,客户端连接新 Master
整个过程自动完成,业务无需人工介入,服务不中断。
五、哨兵的部署
5.1 配置文件
每台哨兵机器的 sentinel.conf:
# 监听主节点(mymaster是自定义名称)
sentinel monitor mymaster 192.168.1.100 6379 2
# 2表示:至少2个哨兵同意才算客观下线
# 主节点密码
sentinel auth-pass mymaster 123456
# 主节点宕机后,多少毫秒内没响应算主观下线
sentinel down-after-milliseconds mymaster 5000
# 故障转移后,同时能同步到几个从节点
sentinel parallel-syncs mymaster 1
5.2 启动哨兵
redis-sentinel /path/to/sentinel.conf
启动多个哨兵实例,每个用不同配置(port不同)。
5.3 Java 客户端连接哨兵
// 配置哨兵地址
Set<String> sentinels = new HashSet<>(Arrays.asList(
"192.168.1.101:26379",
"192.168.1.102:26379",
"192.168.1.103:26379"
));
// Jedis 连接哨兵,自动发现当前主节点
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
try (Jedis jedis = pool.getResource()) {
jedis.set("name", "小明");
}
客户端通过哨兵找到当前的主节点,主节点切换后,哨兵会告知客户端新地址,客户端自动重连。
六、脑裂问题(Split Brain)
6.1 什么是脑裂
哨兵模式下有个经典问题——脑裂。场景:
主节点和哨兵之间的网络断了(但主节点本身没挂)
哨兵判断主节点"客观下线"(多数同意)
触发故障转移,把一个从节点提升为新主节点
同时,原主节点其实还活着,还在接受写请求
→ 现在有两个"主节点"在写数据,两边数据不一致(脑裂)
原主节点网络恢复后,哨兵会让它变成从节点,但它已经写了很多数据,和真正的主节点不一致,这些数据就丢了。
6.2 怎么解决
两个关键配置:
# 主节点必须至少有1个从节点连接
# 否则停止接收写请求
min-slaves-to-write 1
# 从节点与主节点的最大延迟超过10秒
# 主节点也停止接收写请求
min-slaves-max-lag 10
意思是:主节点如果发现自己连不上从节点(或从节点太慢),就拒绝写请求,而不是傻傻地继续写。这样即使发生脑裂,原主节点也不会写入新数据,等它恢复成从节点时,数据还是干净的。
七、Redis Cluster 集群(了解)
主从+哨兵解决了高可用,但还有个问题:数据量太大,一台主节点存不下。
Redis Cluster 是官方的集群方案,解决海量数据问题:
- 把数据分成 16384 个哈希槽(hash slot),分布到多个主节点
- 每个主节点负责一部分槽
- 每个主节点可以有从节点(高可用)
- 客户端根据 key 的哈希值路由到对应节点
Cluster
├── 节点A:槽 0-5460
├── 节点B:槽 5461-10922
└── 节点C:槽 10923-16383
什么时候用 Cluster? 单台 Redis 内存不够、需要横向扩展容量时。中小项目单主+哨兵就够了,不用上集群。
八、选型总结
| 单机 | 无 | 开发测试 |
| 主从复制 | 备份、读压力 | 数据要有备份 |
| 主从 + 哨兵 | 高可用、自动切换 | 生产环境标配 |
| Cluster | 海量数据、横向扩展 | 数据量巨大的场景 |
生产环境标配:主从复制 + 哨兵。 既保证数据有备份,又保证主节点故障自动切换,服务不中断。
本篇小结
- 主从复制:主写从读,数据实时同步,解决备份和读压力
- 全量复制用 RDB 快照,增量复制持续同步,断线用缓冲区补
- 哨兵监控主从,主节点挂了自动把从节点提升为新主,故障转移自动完成
- 哨兵要多实例部署(≥3个),靠"多数同意"避免误判
- 脑裂用 min-slaves-to-write 配置防止主节点孤军写数据
- 数据量太大用 Cluster,把数据分散到多个节点
- 生产标配:主从 + 哨兵
- 下一篇进入高并发专题:缓存穿透、击穿、雪崩
网硕互联帮助中心






评论前必须登录!
注册