Redis 持久化策略(RDB / AOF / 混合持久化)详解(含选型与线上实践)

Redis 持久化策略(RDB / AOF / 混合持久化)详解(含选型与线上实践)

目标:把 Redis 持久化到底怎么选、怎么配、线上怎么排坑讲透。

你会得到:

  • RDB / AOF 的原理与差异
  • 配置项解释(save、appendonly、appendfsync、rewrite 等)
  • 宕机丢数据窗口怎么算
  • 性能影响与优化手段
  • 最推荐的生产配置模板

目录

  • [1. Redis 持久化的本质](#1. Redis 持久化的本质)
  • [2. RDB:快照持久化](#2. RDB:快照持久化)
  • [3. AOF:追加日志持久化](#3. AOF:追加日志持久化)
  • [4. 混合持久化(RDB+AOF)](#4. 混合持久化(RDB+AOF))
  • [5. 怎么选:场景选型表](#5. 怎么选:场景选型表)
  • [6. 线上推荐配置模板](#6. 线上推荐配置模板)
  • [7. 线上观测与排障清单](#7. 线上观测与排障清单)
  • [8. 常见坑与最佳实践](#8. 常见坑与最佳实践)
  • [9. 面试标准回答(1 分钟)](#9. 面试标准回答(1 分钟))

1. Redis 持久化的本质

Redis 是内存数据库,持久化就是回答两个问题:

  1. 我宕机后能恢复到什么程度?(丢数据窗口)
  2. 我付出多少性能成本?(写延迟、IO、fork、磁盘)

Redis 的三种持久化形态:

  • RDB(Snapshot):定期把内存数据做成"快照文件"
  • AOF(Append Only File):把写命令按顺序追加到日志文件
  • 混合持久化:AOF rewrite 时用 RDB 作为基础,再追加增量 AOF

2. RDB:快照持久化

2.1 RDB 是什么

RDB = 某个时刻 Redis 内存数据的"快照"。

文件一般叫 dump.rdb(可配置)。

生成方式:

  • 自动触发:save 规则满足时触发 BGSAVE
  • 手动触发:SAVE(阻塞)/ BGSAVE(后台)
  • 复制场景:主给从全量同步时也会触发生成 RDB(或直接传输)

2.2 生成原理:fork + 写时复制(Copy-on-Write)

  • Redis 主进程 fork() 出子进程
  • 子进程把内存数据写成 RDB 文件
  • 主进程继续响应请求
  • fork 的成本:会瞬间复制页表,内存大时 fork 可能变慢
  • 写时复制:如果主进程在写入期间修改了某页,会触发复制该页(额外内存开销)

2.3 RDB 的优点

  • 恢复快:RDB 是紧凑二进制,加载速度通常比 AOF 回放快
  • 文件小:比 AOF 通常更省空间
  • 对写性能影响相对可控:主要成本在 fork 和磁盘写快照

2.4 RDB 的缺点(你必须知道)

  • 丢数据窗口大 :两次快照之间宕机,期间数据全丢
    比如 save 900 1,最坏可能丢 15 分钟
  • fork/写盘对大内存实例可能造成延迟抖动(尤其是磁盘慢时)

2.5 RDB 配置

conf 复制代码
save 900 1
save 300 10
save 60 10000

dbfilename dump.rdb
dir /var/lib/redis

还有一个很关键的安全项:

conf 复制代码
stop-writes-on-bgsave-error yes

3. AOF:追加日志持久化

3.1 AOF 是什么

AOF 会把 Redis 的写命令(或者等价操作)追加到文件中(appendonly.aof)。

重启恢复时,Redis "回放" AOF 里的命令重建数据。

3.2 AOF 的丢数据窗口(核心看 appendfsync)

conf 复制代码
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
  • always:每次写都 fsync(最安全,最慢)
  • everysec:每秒 fsync(最常用,最坏丢 1 秒左右)
  • no:交给 OS(最快,丢失不可控)

3.3 AOF 文件膨胀与重写(rewrite)

AOF 会越写越大,所以需要 AOF rewrite:

conf 复制代码
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

AOF rewrite 的增量保证(简化):

  • rewrite 期间新写入会进入 rewrite buffer
  • 子进程写完后主进程把 buffer 追加到新 AOF
  • 原子替换文件

3.4 AOF 的优缺点

优点:

  • 丢数据窗口小(everysec)
    缺点:
  • 恢复慢(回放)
  • IO 压力持续
  • rewrite/fork 也会抖动

4. 混合持久化(RDB+AOF)

conf 复制代码
aof-use-rdb-preamble yes

AOF rewrite 时,新 AOF 文件的开头是 RDB 快照,后面是增量命令。

恢复时先加载 RDB 再回放少量 AOF,速度更快。


5. 怎么选:场景选型表

场景 推荐
纯缓存,允许丢 RDB 或关闭持久化(谨慎)
尽量少丢 AOF everysec + 混合持久化
恢复速度要求高 AOF everysec + aof-use-rdb-preamble
写很少,追求极致不丢 AOF always(一般不推荐)

6. 线上推荐配置模板

6.1 通用稳妥(推荐)

conf 复制代码
# RDB 兜底快照
save 900 1
save 300 10
save 60 10000

# AOF
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite yes

# AOF rewrite
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 混合持久化
aof-use-rdb-preamble yes

dir /var/lib/redis

6.2 纯缓存更轻(有风险)

conf 复制代码
appendonly no
save 300 10
save 60 10000

风险:Redis 重启缓存全空,可能导致 DB 被回源打爆(雪崩)。


7. 线上观测与排障清单

bash 复制代码
INFO persistence

关注:

  • rdb_last_bgsave_status
  • aof_enabled
  • aof_rewrite_in_progress
  • aof_current_size / aof_base_size

手动触发:

bash 复制代码
BGSAVE
BGREWRITEAOF

8. 常见坑与最佳实践

  • 大内存实例 fork 抖动:控制单实例内存、磁盘 IO、关闭 THP(常见建议)
  • AOF 太大恢复慢:开启混合持久化 + 合理 rewrite 阈值
  • 磁盘满导致持久化失败:监控磁盘;stop-writes-on-bgsave-error 默认 yes 更安全
  • Sentinel/Cluster 不等于不丢:主从复制异步,failover 也可能丢最近写入,持久化仍重要

9. 面试标准回答(1 分钟)

Redis 持久化有 RDB 和 AOF。RDB 是定期快照,文件小恢复快但丢数据窗口大;AOF 记录写命令,everysec 最坏丢 1 秒,安全性更好但需要 rewrite 控制文件大小。Redis 4.0+ 支持混合持久化,rewrite 时用 RDB preamble 加速恢复,所以线上常用 AOF everysec + aof-use-rdb-preamble yes,再配一定频率的 RDB 兜底。


一句话建议

  • 生产默认:AOF everysec + 混合持久化(aof-use-rdb-preamble yes)
  • RDB 做兜底,但别太频繁
  • 重点关注 fork 抖动与磁盘 IO
相关推荐
IT大白鼠1 天前
Redis 系列 · 第 01 篇——认知入门:Redis 是什么
redis·nosql
彧azz1 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
lbb 小魔仙1 天前
OpenClaw + cpolar 实战:远程 NAS、分享小游戏、RDP,再配置公网 AI 入口
数据库·人工智能·redis·oracle·prometheus
夕除1 天前
redis--018
redis
两锭子1 天前
Redis基础
redis
烟沙九洲1 天前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索1 天前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞1 天前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路2 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog2 天前
Java 接入Redis: 通用命令与键管理
java·服务器·redis