Redis 重启之后数据没了,是最让人心慌的事故之一。要么是没开持久化,要么是配了但没生效。这篇把 RDB 和 AOF 讲清楚。
RDB:快照
按条件触发生成整个数据集的二进制快照:
save 900 1 # 900 秒内至少 1 个 key 变化
save 300 10
save 60 10000
优点:文件紧凑、恢复快、对性能影响小(fork 子进程写)。
缺点:两次快照之间的数据会丢。60 秒一次,最坏丢 60 秒。
fork 的时候如果内存大,会有明显的延迟尖刺(copy-on-write 也要复制页表)。16G 实例 fork 一次可能卡几百毫秒。可以用 save "" 关掉自动 RDB,只留手动 BGSAVE。
AOF:追加日志
每条写命令都记下来:
appendonly yes
appendfsync everysec # 每秒刷盘,最坏丢 1 秒
appendfsync 三档:
| 值 | 丢数据 | 性能 |
|---|---|---|
| always | 几乎不丢 | 最差,每次写都 fsync |
| everysec | 最多 1 秒 | 好,推荐 |
| no | 交给系统 | 最好,可能丢几十秒 |
AOF 文件会越来越大,Redis 会自动重写(auto-aof-rewrite-percentage 100、auto-aof-rewrite-min-size 64mb),也可以在低峰手动 BGREWRITEAOF。
混合持久化
Redis 4.0 之后推荐:
aof-use-rdb-preamble yes
AOF 重写时,前半部分用 RDB 格式(紧凑),后半部分追加增量命令。兼顾恢复速度和数据完整度。
我踩过的坑
坑一:以为开了 AOF 就安全。检查 appendonly 是不是真的 yes,配置文件改完有没有重启或者 CONFIG REWRITE。有次改了配置文件但服务是用命令行参数启动的,配置没生效,重启后数据全丢。
坑二:磁盘满了导致 AOF 写失败。stop-writes-on-bgsave-error yes(默认)会在 RDB 失败时拒绝写入,看起来像「Redis 挂了」。要么保证磁盘空间,要么配合监控。
坑三:主从切换丢数据。主库写入后还没同步到从库就宕机,从库升主,这部分数据没了。异步复制就是这样,要求强一致得用 Redis 之外的方案。
恢复流程
- 停服务
- 备份现有
dump.rdb和appendonly.aof - 把要恢复的文件放到
dir指定的目录 - 启动,看日志里的
DB loaded from append only file
AOF 文件损坏时用 redis-check-aof --fix 修复,会丢掉末尾不完整的命令。
我的配置
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
save 900 1
save 300 100
maxmemory 4gb
maxmemory-policy allkeys-lru
缓存实例其实可以不持久化——数据本来就能重建,重启后回源填充。但队列、锁、session 这类,必须开 AOF。
一句话
RDB 快、AOF 全,混合模式两者兼得。关键是确认配置真的生效,并且定期演练恢复。没演练过的持久化,等于没有。
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://mi-blog.cn/archives/700
共有 0 条评论