← [ BACK_TO_NOTES ]

BodySense Redis 第 7 课:Persistence——RDB、AOF 与 Recovery

从 Redis 是内存系统出发,学习 RDB、AOF、fsync、重启恢复,以及为什么“有持久化”仍不等于“适合做长期业务事实源”。

#course #growing #backend #ops #redis #bodysense

[!info] related notes

BodySense Redis 第 7 课:Persistence——RDB、AOF 与 Recovery

[!abstract] 学习目标 理解:Redis 以内存工作,不代表它一定“重启全丢”;Redis 能持久化,也不代表它自动等价于 PostgreSQL。

先区分四个很容易混在一起的词

这一课最容易犯的错误,是把 Persistence、Durability、Backup、System of Record 全部叫“持久化”。

Persistence

Redis 进程重启或内存丢失后,能否根据磁盘上的数据恢复。

典型手段:RDB / AOF。

Durability

一个已经被系统确认成功的写入,在崩溃后还能保留到什么程度。

它关心的是“已经告诉客户端成功之后,最多还可能丢多少”。

Backup

与在线实例解耦的一份历史副本,用来应对误删、损坏、灾难或回到旧时间点。

System of Record / Source of Truth

从业务架构上,哪套系统拥有这份事实的权威。

所以:

Redis 开 AOF
≠ Redis 自动成为 PostgreSQL 的替代品

PostgreSQL 是 truth
≠ 所有 Redis 都不需要 persistence

这是本课贯穿始终的边界。

为什么“内存里的数据”进程一停就会消失

应用运行时的 RAM 可以粗略想成:

Redis process
└─ address space / RAM
   ├─ keys
   ├─ values
   └─ metadata

如果机器断电或进程退出,RAM 中的数据不会像磁盘文件那样天然长期保存。

因此 Redis 若承载:

纯 Cache
→ 可以接受 cold rebuild

Session / Refresh authority
→ 全丢会造成大批用户被迫重新登录

这两类实例对 Persistence 的需求可以完全不同。

为什么内存数据库还需要持久化

Redis 的工作数据主要在内存:

request
→ memory data structure
→ response

但如果进程退出:

memory disappears

对纯 Cache:

可以重建

对 Session / Refresh authority:

可能导致大批用户掉登录

因此是否启用持久化,取决于数据丢失语义和恢复目标。

RDB Snapshot:把某个时间点的内存状态拍成快照

RDB = Redis Database snapshot。

可以把它类比成:

12:00
Redis memory state
→ 拍照
→ dump.rdb

恢复时不是逐条重放历史命令,而是把快照中的数据集加载回内存。

RDB 的优点

  • 文件通常比较紧凑;
  • 适合作为时间点快照;
  • 恢复时直接加载数据集;
  • 对长期归档/传输比不断增长的原始命令历史更自然。

RDB 的核心 trade-off

如果:

12:00 snapshot
12:05 process crashes

而这 5 分钟没有新的 snapshot / 其他 persistence:

12:00 ~ 12:05 的写入
→ 不在那份 RDB 中

所以 RDB 的 durability window 与 snapshot 频率相关。

Background Save 为什么还会带来成本

Redis 常用后台子进程生成 snapshot。在支持 fork 的系统上,这涉及 fork + copy-on-write。

可以先建立直觉:

父进程继续服务请求
子进程写 snapshot

如果 snapshot 期间大量内存页继续被修改,copy-on-write 会带来额外内存压力;同时还有磁盘 I/O。

所以“后台保存”不等于“完全没有性能成本”。

AOF:记录写操作,让 Redis 可以重放历史恢复状态

AOF = Append Only File。

思路和 RDB 不同:

RDB
→ 保存“某个时间点现在长什么样”

AOF
→ 保存“哪些写操作改变了数据”

例如概念上记录:

SET a 1
SADD user_sessions:u1 s1
DEL session:s2
...

重启时:

read persisted AOF
→ replay effects
→ rebuild in-memory dataset

Redis 官方当前文档中,Redis 7 起使用 multi-part AOF:通常由 base file + 后续 incremental files 组成,并由 manifest 管理。这个实现细节不改变核心心智模型:AOF 仍然是通过持久化写入效果来支持恢复。

Append Only 不等于“每个命令立刻进物理磁盘”

操作系统本身有 page cache / write buffer。

粗略链路:

Redis
→ write()
→ OS buffer/page cache
→ fsync / storage flush
→ durable storage

因此 appendfsync 的意义就是决定 Redis 多积极地要求操作系统把 AOF 数据刷到持久介质。

appendfsync

重要选项:

always

每次写入都尽量 fsync

更强 durability,I/O 代价更高。

everysec

大约每秒 fsync

常见折中:

性能较好
+
极端 crash 时可能损失约一小段最近写入

no

把 fsync 调度更多交给操作系统,性能更轻,但 durability window 更不明确。

BodySense 当前配置

生产 Redis 当前已经:

appendonly yes
appendfsync everysec
persistent volume

这意味着:

Redis 不只是“进程死了必然全清空”的纯临时实例。

但仍需问:

AOF 文件所在 volume 是否可靠?
恢复是否验证过?
容灾 / backup 是否存在?
failover 时复制语义如何?

Persistence ≠ Backup

这两个概念必须分开。

Persistence
→ 进程重启后尽量恢复最近状态

Backup
→ 有独立时间点副本,可在误删、损坏、灾难后恢复

如果操作员错误执行:

DEL critical:key

AOF 可能忠实记录这个删除。

所以:

“有 AOF”并不能代替备份和灾难恢复设计。

Persistence ≠ System of Record

这是本课最重要的判断。

即使 Redis 有 AOF:

BodyState
Diagnosis
Treatment
Runtime Event durable log
Job ledger

仍然不应因此默认迁成 Redis-only。

这些状态通常需要:

  • 关系约束;
  • 多实体事务;
  • 历史查询;
  • 审计;
  • replay;
  • durable ownership;
  • 数据迁移与分析。

Redis 持久化解决的是:

Redis 自己的恢复能力。

而 PostgreSQL 的 domain authority 是另一层架构问题。

AOF Rewrite:日志可以压缩成“重建当前状态所需的最小效果”

如果 AOF 永远只是追加:

SET counter 1
SET counter 2
SET counter 3
...
SET counter 1000000

文件会不断增大。

但恢复当前状态并不需要保留每一次历史覆盖。

理论上当前结果只需要类似:

SET counter 1000000

所以 Redis 会进行 AOF rewrite:

old AOF history
→ 根据当前 dataset 生成更紧凑 base
→ 继续接收增量写
→ 切换到新的 AOF 组合

这不是“修改历史业务审计日志”,因为 AOF 本来就不是给人做业务审计的 event log;它的目标是恢复 Redis 当前数据集。

Rewrite 也有资源成本

需要关注:

CPU
memory / copy-on-write
disk throughput
disk free space
rewrite duration
latency spike

所以运维上不仅要问:

AOF 开了吗?

还要问:

rewrite 是否健康、磁盘是否够、恢复有没有实际验证过?

RDB + AOF

不是只能二选一。

可以同时使用:

RDB
→ 快照 / 备份友好

AOF
→ 更细粒度写入恢复

最终策略由:

可接受数据丢失窗口
恢复时间
I/O 预算
数据是否可重建

决定。

BodySense 思考题

如果 Redis 丢掉最近 1 秒:

Session

可能:

刚创建的 Session 消失
→ 用户刚登录就被迫重新登录

Refresh Rotation

更微妙:

旧 token consumed / replay tombstone
新 token active

如果 crash/recovery 回到一个不一致的时间点,必须确认安全语义是否仍可接受。

所以不能只说:

“AOF everysec 很安全。”

而要具体分析每种 key 的 recovery semantics。

Lab

在开发环境隔离实验:

1. 写入带 TTL / 不带 TTL 的 Key
2. restart Redis container
3. 检查恢复
4. 查看 AOF / persistence INFO
5. 在独立实验配置下比较 no persistence / AOF / RDB

不要直接修改生产策略。

Prediction

[!question]

  1. RDB 和 AOF 最直观的区别是什么?
  2. appendfsync everysec 是否意味着绝对不会丢最近 1 秒?
  3. 有 AOF 后,Redis 能否自动取代 PostgreSQL 成为 BodyState 的唯一事实源?
  4. Persistence 为什么不能替代 Backup?
  5. 对一个纯 Cache Redis,是否一定需要 AOF?

[!success]- Answer / 解析 1. RDB 和 AOF 最直观的区别是什么?
RDB 保存某个时间点的状态快照;AOF 记录可重放的写操作历史。前者更像定期拍照,后者更像持续记账。

2. appendfsync everysec 是否意味着绝对不会丢最近 1 秒?
不是。它表示常见策略是大约每秒把 AOF 刷到持久存储,是 durability 与性能的折中,不是严格“最多只丢 1.000 秒”的数学保证。操作系统调度、硬件、崩溃类型和底层存储都可能影响实际窗口。

3. 有 AOF 后,Redis 能否自动取代 PostgreSQL 成为 BodyState 的唯一事实源?
不能。AOF 提升的是 Redis 自身的恢复能力;BodyState 是否应由 PostgreSQL 持有,取决于事务、关系约束、历史审计、查询、数据治理和 domain ownership。durable Redis 不等于 relational domain database。

4. Persistence 为什么不能替代 Backup?
Persistence 会忠实保存很多错误操作。例如误执行 DEL critical:key,AOF 也可能把删除记录下来。Backup 是与在线实例解耦的历史恢复点,主要解决误删、损坏、灾难和时间点恢复问题。

5. 纯 Cache Redis 是否一定需要 AOF?
不一定。如果所有数据都能从 PostgreSQL 等事实源安全重建,而且可以接受 Redis 重启后的 cold cache,那么关闭持久化可能更简单。是否启用应由重建成本、恢复时间和用户体验决定,而不是“生产 Redis 必须 AOF”。

L4 Gate

能根据四个问题做持久化决策:

Redis 数据能否重建?
最多能接受丢多少?
恢复要多快?
持久化 I/O 对延迟是否可接受?

并解释:

durability 是存储属性,system of record 是业务所有权属性。两者不是同一个维度。

创建于 2026/9/18 更新于 2026/9/18
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本