重启不丢数据?Redis 持久化与主从同步全解析(通俗版)
导读:Redis 号称“内存数据库”,速度飞快,但大家都知道断电后内存数据会丢失。那为什么生产环境的 Redis 重启后数据还在?
答案就是:持久化。
今天我们就用大白话聊聊 Redis 是怎么把内存数据“存盘”的,以及多台 Redis 之间是如何“复制粘贴”数据的。
一、为什么要持久化?
想象一下,Redis 是一个超级速记员,所有数据都记在他的脑子里(内存)。
- 优点:反应极快,读写速度是硬盘的几十万倍。
- 缺点:一旦停电或服务器宕机,他脑子里的东西就全忘了(数据丢失)。
持久化,就是给这个速记员配了一个笔记本。他会定期把脑子里的重要数据抄写到笔记本(硬盘)上。下次重启时,先读笔记本,把数据恢复到大脑里。
Redis 提供了两种“抄写”方式:RDB 和 AOF。
二、RDB:定时拍快照(Snapshot)
1. 是什么?
RDB (Redis Database) 就像给数据拍照片。
每隔一段时间(比如 5 分钟),或者当数据变化达到一定次数,Redis 就会把当前内存里的所有数据,打包压缩成一个二进制文件(默认叫 dump.rdb),保存到硬盘上。
2. 工作流程
- Redis 收到保存指令(或触发配置)。
- fork 一个子进程(父进程继续干活,不阻塞)。
- 子进程把内存数据写入临时文件。
- 写入完成后,替换旧的
dump.rdb。
3. 优缺点
| 优点 | 缺点 |
|---|---|
| ✅ 文件紧凑:二进制文件小,适合备份、传输。 | ❌ 数据可能丢失:如果两次快照之间宕机,这段时间的数据就没了。 |
| ✅ 恢复速度快:加载二进制文件比一条条重放命令快得多。 | ❌ 大数据量卡顿:虽然子进程处理,但 fork 瞬间如果数据很大,可能导致主线程短暂停顿(毫秒级)。 |
| ✅ 性能影响小:子进程操作,对主进程影响最小。 | ❌ 无法细粒度恢复:只能恢复到上一次快照的状态。 |
4. 适用场景
- 允许丢失几分钟数据(如缓存层)。
- 需要定期备份数据到冷存储。
- 希望重启恢复速度越快越好。
三、AOF:记录每一笔流水账(Append Only File)
1. 是什么?
AOF (Append Only File) 就像记账本。
Redis 执行的每一条写命令(如 SET, DEL, INCR),都会以文本形式追加记录到 appendonly.aof 文件末尾。
重启时,Redis 会把文件里的命令从头到尾重新执行一遍,数据就恢复了。
2. 三种同步策略(fsync)
既然要记帐,什么时候写入硬盘呢?
- always:每来一条命令,立刻写盘。最安全,但最慢(性能接近硬盘 IO)。
- everysec(推荐):每秒写一次盘。兼顾安全与性能(最多丢失 1 秒数据)。
- no:不主动写盘,靠操作系统决定何时刷盘。最快,但最不安全(宕机可能丢失大量数据)。
3. AOF 重写(Rewrite)
问题:如果你对一个键执行了 100 次 INCR,AOF 文件会记录 100 行命令。其实只需要记录最终结果 SET key 100 即可。
解决:当 AOF 文件太大时,Redis 会启动重写机制。子进程读取当前内存数据,生成一条能还原当前状态的最小命令集,替换旧文件。
注意:重写不是读取旧 AOF 文件合并,而是直接读取当前内存生成新文件。
4. 优缺点
| 优点 | 缺点 |
|---|---|
✅ 数据更安全:配置 everysec 最多只丢 1 秒数据。 | ❌ 文件体积大:同样的数据,AOF 文件通常比 RDB 大。 |
| ✅ 可读性强:文本文件,可以手动修改修复(比如误删了数据,可以把删除命令删掉再重启)。 | ❌ 恢复速度慢:需要一条条重放命令,数据量大时恢复慢。 |
| ✅ 灵活:支持不同刷盘策略。 | ❌ 性能开销:虽然异步,但频繁写盘仍有一定 IO 压力。 |
5. 适用场景
- 对数据安全性要求高,不能容忍丢失。
- 需要审计操作记录。
四、RDB vs AOF:怎么选?
| 维度 | RDB | AOF |
|---|---|---|
| 数据完整性 | 低(可能丢几分钟) | 高(最多丢 1 秒) |
| 恢复速度 | 快 | 慢 |
| 文件大小 | 小 | 大 |
| 性能影响 | 小 | 中/大(取决于策略) |
最佳实践:混合使用(Redis 4.0+)
现在的生产环境,通常同时开启 RDB 和 AOF。
- 恢复时:优先加载 AOF(因为数据更全)。
- AOF 重写时:采用混合持久化模式。新 AOF 文件的前半部分是 RDB 格式的快照(快速加载),后半部分是新产生的增量命令。
- 效果:既保证了数据安全性,又极大提升了恢复速度。
配置示例 (redis.conf):
# 开启 AOF
appendonly yes
# 每秒同步
appendfsync everysec
# 开启混合持久化
aof-use-rdb-preamble yes五、数据同步:主从复制(Replication)
持久化解决了单机断电问题,但如果硬盘坏了怎么办?或者想实现读写分离提升性能?
这就需要主从复制。
1. 角色介绍
- Master(主):负责写操作,并将数据同步给 Slave。
- Slave(从):负责读操作(可选),实时同步 Master 的数据。
2. 同步流程(全量 + 增量)
第一阶段:全量复制(初次连接)
- Slave 上线:发送
PSYNC命令给 Master。 - Master 快照:执行
bgsave生成 RDB 文件。 - 缓冲命令:在生成 RDB 期间,Master 把新的写命令存入复制缓冲区。
- 发送文件:Master 把 RDB 文件发给 Slave。
- Slave 加载:Slave 清空旧数据,加载 RDB。
- 补发命令:Master 把缓冲区的命令发给 Slave,Slave 执行。
- 完成:此时主从数据一致。
第二阶段:增量复制(日常运行)
- 之后 Master 每执行一条写命令,就顺手发给所有 Slave。
- Slave 收到后立即执行,保持实时一致。
第三阶段:断线重连(心跳检测)
- 如果网络断了又好了,不需要重新全量复制!
- Slave 会告诉 Master:“我上次收到的是第 X 条命令”。
- Master 从缓冲区找第 X 条之后的命令发给 Slave(部分复制)。
- 只有当缓冲区数据没了,才被迫全量复制。
3. 拓扑结构
- 一主一从:最简单,做备份。
- 一主多从:分担读压力(读写分离)。
- 树状结构:Slave 也可以作为下一级 Master(Master -> Slave1 -> Slave2),减少 Master 带宽压力。
4. 常见问题
- 数据不一致:网络延迟可能导致 Slave 数据稍微滞后(毫秒级)。
- 脑裂问题:如果 Master 网络分区,Sentinel 可能会选举新 Master。旧 Master 恢复后变成 Slave,期间写入的数据可能会丢失(需配置
min-slaves-to-write规避)。
六、总结与建议
1. 持久化配置建议
- 必须开启 AOF:策略选
everysec。 - 开启混合持久化:
aof-use-rdb-preamble yes。 - RDB 作为辅助:可以配置定时快照用于冷备,但主要依赖 AOF 恢复。
- 不要在一台机器上做持久化:持久化会消耗磁盘 IO,尽量在从节点做,或者使用独立的磁盘。
2. 高可用架构建议
- 单机不够用:至少部署 一主一从。
自动故障转移:配合 Redis Sentinel(哨兵) 或 Redis Cluster(集群)。
- 哨兵:监控主节点,挂了自动提拔从节点为主。
- 集群:数据分片存储,多主多从,横向扩展。
3. 一句话口诀
RDB 快照快恢复,AOF 日志保安全;
混合模式是首选,主从复制防单点;
每秒刷盘最均衡,哨兵集群保高可用。
你的公司 Redis 是用的哪种持久化方式?欢迎在评论区分享!
(觉得有用,记得点赞收藏,欢迎关注、一起学习、无线进步!)