不能只用RDB或AOF:RDB定时快照,宕机易丢数据;AOF虽记录命令但有1秒丢失风险、体积膨胀快且重写可能失败;混合使用(RDB+AOF)兼顾速度与完整性。

为什么不能只用RDB或只用AOF
RDB 是定时快照,save 或 bgsave 触发时才落盘,两次快照之间宕机就丢数据;AOF 记录每条写命令,默认每秒刷盘(appendfsync everysec),但仍有最多 1 秒丢失风险,且 AOF 文件体积膨胀快、重写(bgrewriteaof)期间可能阻塞或出错。
常见错误是“开了 AOF 就以为万无一失”,结果发现磁盘满导致 AOF 写失败,Redis 直接停写(取决于 no-appendfsync-on-rewrite 和 stop-writes-on-bgsave-error 配置)。
- RDB 适合备份和灾难恢复,恢复快、文件小,但粒度粗
- AOF 适合高可靠性场景,可配置为每次写都 fsync(
appendfsync always),但吞吐暴跌,一般不推荐 - 混合使用才是生产常态:RDB 提供基础快照锚点,AOF 补充增量变更
如何开启混合持久化(RDB+AOF)
Redis 4.0+ 支持 aof-use-rdb-preamble yes,开启后 AOF 重写时不再纯文本追加命令,而是先写入一个紧凑的 RDB 格式头部,再接增量 AOF 命令。重启时 Redis 先加载 RDB 部分,再重放后续 AOF 日志,兼顾速度与完整性。
关键配置项:
-
appendonly yes—— 必须开启 AOF -
aof-use-rdb-preamble yes—— 启用混合模式(默认关闭) -
save 900 1、save 300 10等 —— RDB 触发条件仍保留,用于手动备份或监控抓取 -
auto-aof-rewrite-percentage 100和auto-aof-rewrite-min-size 64mb—— 控制 AOF 重写时机,避免频繁 rewrite
注意:bgrewriteaof 过程中若磁盘空间不足,AOF 文件会被清空并报错 Failed to open the temp AOF file: No space left on device,此时需预留至少 2 倍当前 AOF 大小的空闲空间。
RDB 与 AOF 冲突时以谁为准
Redis 启动时优先加载 AOF(如果 appendonly yes 且 AOF 文件存在),完全忽略 RDB 文件;只有 AOF 关闭或 AOF 文件损坏/不存在时,才尝试加载 dump.rdb。
所以:
- 不要以为“RDB 文件更新”就能覆盖 AOF 的状态——它不会被读
- 若误删 AOF 但 RDB 较新,可临时关掉
appendonly,启动后再用bgrewriteaof重建 AOF - AOF 文件校验失败(如末尾截断)会导致启动失败,报错
Bad file format reading the append only file,此时需用redis-check-aof --fix修复
哪些操作会意外清空或跳过持久化
有些命令看似安全,实则绕过 AOF/RDB 机制:
-
FLUSHALL和FLUSHDB默认会写入 AOF(除非配置flushall-as-truncate-aof yes,此时改写为 TRUNCATE 命令,更轻量) -
CONFIG SET修改持久化参数(如appendfsync no)不会触发重写,但会影响后续日志行为 - 主从切换时,从库执行
SLAVEOF NO ONE成为主库后,若未配置 AOF,它不会自动继承原主库的 AOF 状态 - 使用
redis-cli --pipe批量导入时,若服务端 AOF 开启且appendfsync always,性能极差;建议先导出为 RDB,再用cat dump.rdb | redis-cli --pipe加速
混合持久化不是“开个开关就万事大吉”,AOF 重写逻辑、磁盘水位、配置优先级这些细节,往往在凌晨三点故障时才暴露出来。










