rdb快照无法避免数据丢失,因其仅保存定时点的内存状态,两次快照间的新写入未落盘即崩溃便会丢失;须配合aof(如everysec)或混合持久化才能有效防丢。

为什么RDB快照再快,也挡不住数据丢失?
RDB 本质是定时快照——它只保存「某一时刻」的内存状态,两次快照之间的写入操作,只要没来得及落盘,断电或崩溃就直接蒸发。这不是 Redis 的 bug,而是 RDB 的设计取舍:用时间换速度,用间隔换性能。
比如默认配置 save 900 1(900 秒内至少 1 次修改才触发),意味着最坏情况下可能丢掉 15 分钟的数据;而生产环境若设成 save 60 10000,看似激进,但若写入突增、fork 耗时变长,反而更容易触发 OOM 或超时失败。
- RDB 是 fork 子进程做的,主进程继续写,但子进程只拷贝 fork 那一刻的内存页(靠 COW)——所以它“看不见” fork 后的新写入
- 客户端执行
SAVE会阻塞所有请求,线上严禁使用;BGSAVE虽不阻塞,但频繁调用会加重 fork 开销和内存压力 - RDB 文件生成后,还要等 fsync 写盘才算真正安全;如果配置了
stop-writes-on-bgsave-error yes,一次磁盘满或权限错就会让 Redis 拒绝写入
怎么让 RDB 不那么“敢丢”?——调参不是越密越好
关键不在“多久存一次”,而在“什么时候必须存”。要结合业务容忍度和机器负载动态权衡,而不是盲目压缩时间窗口。
- 检查当前触发条件:
CONFIG GET save,确认是否仍用默认的save 3600 1这类宽松策略 - 写密集场景建议启用双阈值,例如
save 300 100(5 分钟内 100 次修改) +save 60 1000(1 分钟内 1000 次),避免低频写入长期不快照 - 禁用
save ""(即关闭自动 RDB)后,务必搭配 AOF 或外部备份工具,否则等于裸奔 - 监控
latest_fork_usec(单位微秒),持续超过 500000(0.5 秒)说明 fork 压力大,需考虑降低vm.overcommit_memory或升级内存
当 RDB 已经在跑了,新写入到底安不安全?
安全,但仅限于“不被 RDB 进程干扰”——RDB 子进程和主进程内存隔离,你写你的,它存它的。可这恰恰埋下幻觉:以为“正在持久化=数据已保底”,其实刚写的 key 还在内存里飘着,没进 RDB,也没进 AOF(如果 AOF 关着)。
- 用
INFO persistence查看rdb_bgsave_in_progress:1时,rdb_last_bgsave_status:ok只代表上一次成功,不代表当前写入已被覆盖 - 若同时开了 AOF,且
appendfsync everysec,那最多丢 1 秒数据;但如果 AOF 关了,RDB 又卡在 fork 阶段,那一秒写入就是纯易失的 -
redis-cli --rdb /tmp/dump.rdb这种手动导出,走的是 debug 模式,不经过正常 RDB 流程,不能替代配置的自动触发
真正防丢,RDB 必须配合什么?
单靠 RDB,永远解决不了“最后一次快照之后”的空白。它只是基础防线,不是保险柜。
- 强制开启 AOF:
appendonly yes,并设为appendfsync everysec(平衡性能与安全性),RDB + AOF 混合持久化(aof-use-rdb-preamble yes)在 Redis 4.0+ 更推荐 - 定期把
dump.rdb和appendonly.aof同步到异地存储,注意文件权限和原子写(如用rsync --inplace配合rename替换) - 避免依赖 RDB 恢复“最新状态”:RDB 加载是全量覆盖,若误删 key 后又做了 RDB,恢复只会把误删状态固化——这时必须靠 AOF 重放或从备份时间点回溯
最容易被忽略的一点:RDB 文件本身不是“最终答案”,它是某个瞬间的快照,而业务需要的往往是“某个时间点之前的所有变更”。这个 gap,只能靠 AOF 日志填,或者靠应用层双写兜底。










