数据持久化
深夜的故障
Redis 方案上线后,系统运行稳定,性能提升了 100 倍。
我以为可以高枕无忧了,直到有一天…
凌晨 3 点,手机响了。
【监控报警】Redis 服务器重启
时间:2023-08-15 03:12:45
原因:服务器内存溢出,自动重启
状态:服务已恢复
我打开电脑,查看 Redis 状态:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
数据全部丢失了!
所有文章的点赞数都变成了 0,用户看不到自己的点赞记录。
这是一次严重的数据丢失事故。
为什么数据丢失?
我查阅了 Redis 的文档,找到了原因:
Redis 数据存储在内存中:
- 读写速度极快(纳秒级)
- 但内存是易失性存储
- 服务器重启后,内存数据丢失
默认配置:
- 没有开启持久化
- 重启后数据全部丢失
我忽略了数据持久化!
Redis 持久化方案
Redis 提供了两种持久化方案:
方案 1:RDB(快照)
原理:
- 定期将内存中的数据保存到磁盘
- 生成一个快照文件(dump.rdb)
- 重启时加载快照恢复数据
配置方式:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
手动触发快照:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
优点:
- 文件紧凑,适合备份
- 恢复速度快(直接加载文件)
- 对性能影响小(异步保存)
缺点:
- 可能丢失最后一次快照后的数据
- 快照生成期间,数据量大时会影响性能
数据丢失窗口:
配置:save 60 10000
时间线:
T0: 生成快照 dump.rdb
T1 ~ T60: 10000 次点赞操作
T60: 触发新的快照
如果在 T45 服务器宕机:
- 丢失 T1 ~ T45 的 7500 次点赞数据
- 只能恢复 T0 时刻的数据
方案 2:AOF(追加文件)
原理:
- 记录所有写操作命令
- 追加到文件末尾(appendonly.aof)
- 重启时重新执行所有命令恢复数据
配置方式:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
AOF 文件内容示例:
*3
$3
SET
$23
article:123:like_count
$4
1000
*3
$4
INCR
$23
article:123:like_count
*3
$4
SADD
$25
article:123:liked_users
$3
101
优点:
- 数据更安全,最多丢失 1 秒数据
- 文件可读,便于分析
- 支持重写,压缩文件大小
缺点:
- 文件体积大
- 恢复速度慢(需要重放所有命令)
- 对性能有影响(频繁写磁盘)
AOF 重写:
随着操作增多,AOF 文件越来越大:
原始操作:
INCR article:1:like_count → 1
INCR article:1:like_count → 2
INCR article:1:like_count → 3
...
INCR article:1:like_count → 100
重写后:
SET article:1:like_count 100
重写效果:
- 文件大小减少 90%
- 恢复速度提升
配置 AOF 重写:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
方案 3:RDB + AOF(推荐)
原理:
- 同时开启 RDB 和 AOF
- AOF 保证数据安全
- RDB 加快恢复速度
配置方式:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
恢复流程:
Redis 重启:
1. 检查是否存在 AOF 文件
2. 如果存在,加载 AOF 文件恢复数据
3. 如果不存在,检查 RDB 文件
4. 如果存在,加载 RDB 文件恢复数据
5. 如果都不存在,启动空的 Redis
优缺点:
| 方案 | 数据安全 | 恢复速度 | 性能影响 | 推荐场景 |
|---|---|---|---|---|
| RDB | 低 | 快 | 小 | 允许丢失几分钟数据 |
| AOF | 高 | 慢 | 中 | 不能丢失数据 |
| RDB + AOF | 最高 | 中 | 中 | 生产环境推荐 |
点赞场景的持久化策略
分析需求
点赞数据特点:
1. 写入频繁:每秒可能有数千次点赞
2. 重要性高:用户点赞数据不能丢失
3. 数据量大:数百万篇文章,每篇数千点赞
持久化需求:
- 尽量少丢失数据
- 恢复时间可接受
- 对性能影响最小
推荐配置
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
效果:
数据安全性:
- 最多丢失 1 秒数据(AOF)
- 即使 AOF 损坏,还能用 RDB 恢复大部分数据
恢复速度:
- 优先加载 AOF:数据完整
- 如果 AOF 损坏,加载 RDB:数据基本完整
性能影响:
- AOF 每秒同步:对性能影响约 10%
- RDB 定期快照:对性能影响约 5%
- 总体影响:约 15%(可接受)
数据丢失后的恢复
即使配置了持久化,仍可能发生数据丢失。我需要一个恢复方案。
方案:数据库同步 + 缓存重建
思路:
- Redis 作为缓存,数据库作为数据源
- 定期将 Redis 数据同步到数据库
- Redis 数据丢失后,从数据库重建
实现:
定时任务配置:
实际效果
配置持久化后
Redis 配置:
- RDB:每分钟保存一次快照
- AOF:每秒同步一次
效果:
- 重启后数据自动恢复
- 最多丢失 1 秒数据
- 对性能影响约 15%
监控数据
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
性能对比
无持久化:
- 写入吞吐量:约 8000 ops/s
- 响应时间:0.1ms
RDB 持久化:
- 写入吞吐量:约 7500 ops/s(-6%)
- 响应时间:0.12ms
AOF 持久化(everysec):
- 写入吞吐量:约 7000 ops/s(-12%)
- 响应时间:0.15ms
RDB + AOF:
- 写入吞吐量:约 6500 ops/s(-19%)
- 响应时间:0.18ms
结论:性能损失可接受,数据安全性大幅提升
课后练习
练习 1
RDB 和 AOF 各有什么优缺点?如何选择?
RDB vs AOF 对比:
| 特性 | RDB | AOF |
|---|---|---|
| 原理 | 定期快照 | 追加写命令 |
| 文件大小 | 小(压缩二进制) | 大(文本命令) |
| 恢复速度 | 快 | 慢 |
| 数据安全 | 低(可能丢失分钟级数据) | 高(最多丢失 1 秒) |
| 性能影响 | 小 | 中等 |
| 可读性 | 不可读 | 可读 |
RDB 优缺点详解:
优点:
1. 文件紧凑
- 压缩后的二进制格式
- 适合备份和传输
- 文件大小通常是内存数据的 50%~80%
2. 恢复速度快
- 直接加载到内存
- 大数据集恢复时间秒级
3. 对性能影响小
- 异步保存,不阻塞主线程
- 可以设置保存间隔
缺点:
1. 数据安全性低
- 只能保存最近一次快照的数据
- 两次快照之间的数据可能丢失
- 如果 Redis 崩溃,丢失最后一次快照后的所有数据
2. 快照生成时可能影响性能
- 数据量大时,fork 子进程消耗内存
- 写时复制(Copy-on-Write)可能占用额外内存
3. 不适合实时持久化
- 频繁快照会影响性能
- 不适合对数据完整性要求高的场景AOF 优缺点详解:
优点:
1. 数据安全性高
- appendfsync always:每次写操作都同步,不丢失数据
- appendfsync everysec:每秒同步,最多丢失 1 秒数据
2. 文件可读
- 文本格式,可以直接查看
- 便于分析和修复
- 误操作时可以手动修改文件恢复
3. 支持重写
- 自动压缩 AOF 文件
- 减少文件体积
- 加快恢复速度
缺点:
1. 文件体积大
- 记录所有写命令
- 文件大小远大于 RDB
- 需要定期重写
2. 恢复速度慢
- 需要重放所有命令
- 大数据集恢复时间分钟级
3. 对性能影响较大
- 每次写操作都要记录
- 频繁磁盘 IO
- appendfsync always 会严重影响性能选择建议:
场景 1:只用于缓存(数据可以丢失)
→ 只用 RDB,或不开启持久化
场景 2:数据不能丢失,但允许丢失少量
→ AOF + appendfsync everysec
场景 3:数据非常重要,不能丢失
→ RDB + AOF(双保险)
场景 4:数据量很大,恢复时间要短
→ RDB 为主,AOF 为辅点赞场景选择:
点赞数据:
- 数据重要,不能丢失
- 写入频繁
- 需要快速恢复
推荐:RDB + AOF
- AOF 保证数据安全
- RDB 加快恢复速度
- 定期同步到数据库作为最终备份练习 2
如何配置 Redis 持久化,平衡性能和数据安全?
生产环境推荐配置:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
不同业务场景的配置:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
性能优化技巧:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
监控和调优:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
练习 3
AOF 文件损坏后如何修复?
AOF 文件损坏场景:
场景 1:写入过程中断电
- 最后一条命令可能不完整
场景 2:磁盘空间不足
- 文件可能被截断
场景 3:系统崩溃
- 文件可能损坏修复方法 1:Redis 自带工具
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
修复方法 2:手动修复
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
修复方法 3:使用 RDB 恢复
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
修复方法 4:从数据库恢复
预防措施:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
完整修复流程:
发现 AOF 文件损坏:
1. 停止 Redis 服务
2. 备份当前 AOF 文件
3. 尝试 redis-check-aof --fix
4. 如果修复失败,使用 RDB 恢复
5. 如果 RDB 也损坏,从数据库恢复
6. 重启 Redis 并验证数据
7. 分析原因,防止再次发生练习 4
如何实现 Redis 数据的跨机房备份?
跨机房备份方案:
方案 1:主从复制
架构:
机房东:
Redis Master(读写)
机房 B:
Redis Slave(只读)
复制流程:
1. Master 写入数据
2. 异步复制到 Slave
3. 机房 B 有完整数据副本配置主从复制:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
方案 2:Redis Sentinel(哨兵)
架构:
机房东:
Redis Master
Sentinel 1
机房 B:
Redis Slave
Sentinel 2
第三方机房:
Sentinel 3
故障转移:
1. Sentinel 监控 Master
2. 发现 Master 故障
3. 选举新 Master
4. 通知客户端切换Sentinel 配置:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
方案 3:Redis Cluster
架构:
机房东:
Master 1, Master 2, Master 3
机房 B:
Slave 1, Slave 2, Slave 3
数据分片:
- 每个节点负责一部分数据
- Slave 作为备份
- 支持 Master 故障自动切换方案 4:定期快照备份
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
定时备份:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
跨机房恢复:
容灾演练脚本:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
练习 5
如何监控 Redis 持久化状态,及时发现潜在问题?
Redis 持久化监控指标:
验证要点
- 命令只用于验证系统状态,读者不需要记具体参数。
监控脚本:
Prometheus + Grafana 监控:
配置要点
- 配置表达的是环境差异和运行参数,不是业务规则本身。
- 队列、缓存、存储和服务参数决定系统在高峰期的缓冲能力。
Grafana 告警规则:
配置要点
- 配置表达的是环境差异和运行参数,不是业务规则本身。
- 队列、缓存、存储和服务参数决定系统在高峰期的缓冲能力。
监控仪表板指标:
RDB 指标:
- 上次保存时间
- 保存后的修改次数
- 保存状态
- 保存耗时趋势
AOF 指标:
- AOF 开启状态
- 文件大小
- 重写状态
- 重写耗时趋势
- fsync 延迟次数
通用指标:
- 内存使用量
- 连接数
- 命令执行次数
- 键空间大小思考题
-
如果 Redis 内存不够,但又需要持久化,如何优化?
-
AOF 重写过程中,新的写操作如何处理?
-
如何实现”增量持久化”,只持久化变化的数据?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
