Redis 持久化:RDB 与 AOF

为什么需要持久化?

Redis 虽然快,但它的数据主要存储在内存中,而内存属于易失性存储介质。

一旦断电或者服务重启,如果没有持久化机制,数据就可能丢失。

所以 Redis 提供了两种持久化方案:RDBAOF,前者是数据快照,后者是命令日志。

面试的时候面试官常问这个问题,很多人只答出"两种方案"就结束了,其实还需要深入讲清楚原理和取舍。

RDB:数据快照

什么是 RDB?

RDB(Redis Database Backup)就是把某一时刻的内存数据完整写入磁盘,生成一个二进制文件。下次启动时,Redis 读取这个文件,把数据恢复到内存里。

说人话就是:

给内存拍一张照片,事后按照片还原。

手动触发

可以用两条命令手动生成 RDB 文件:

  • SAVE:由主进程执行,会阻塞所有其他操作。文件大时风险很高,生产环境基本不用。
  • BGSAVE:由子进程执行,异步操作,对主进程影响极小。生产环境用这个

自动触发

Redis 配置文件里有三行默认规则,Redis 会周期性检查 save 配置,当任意条件满足时,会触发后台执行 BGSAVE。

plain 复制代码
save 900 1       # 900 秒内至少有 1 个 key 被修改
save 300 10      # 300 秒内至少有 10 个 key 被修改
save 60 10000    # 60 秒内至少有 10000 个 key 被修改

你可以根据业务情况修改这些阈值。

RDB 的执行原理

很多人知道 BGSAVE 用子进程,但不知道为什么不会阻塞主进程

这就要从内存模型说起。

Linux 系统中,进程不能直接操作物理内存,而是通过虚拟内存 + 页表来间接访问。

页表记录了虚拟地址和物理地址的映射关系。

执行 BGSAVE 时,Redis 会 fork 出一个子进程。

关键点在于:fork 只复制页表,不复制数据

子进程拿到与主进程相同的映射关系后,就能读取相同的物理内存数据,而无需拷贝任何实际内容。 fork 本身不会复制大量数据,只需要复制页表,因此相比完整复制内存开销非常小。

Copy on Write 解决了什么?

子进程在写 RDB 文件的同时,主进程也在接收用户的写请求。

如果两者直接共享内存,就会出现读写冲突,产生脏数据

解决办法是 Copy on Write(写时复制)

fork 之后,共享内存被标记为只读。

当主进程收到写请求时,操作系统会把被修改的内存页单独拷贝一份,主进程写新副本,子进程继续读旧副本。

这样就避免了数据竞争。

说人话就是:

有人要改,我就抄一份给你改,原文件不动

AOF:命令日志

什么是 AOF?

AOF(Append Only File)记录的是 Redis 执行的每一个写命令。

每次执行写操作,命令就会被追加到 AOF 文件末尾。

说人话就是:

把所有写操作写成日记,重启时重放日记就能恢复数据。

比如你执行了三条命令:

plain 复制代码
SET number 123
SET name jack
SET number 666

AOF 会按照 Redis 协议格式记录每一次写命令,而不是简单保存命令字符串。

开启与刷盘策略

AOF 默认是关闭的,需要在配置文件中将 appendonly 改为 yes

AOF 有三种刷盘频率:

策略 说明 可靠性 性能
always 每次写命令都立即刷盘 最高,几乎不丢数据 最差
everysec 每秒执行一次 fsync 较高, 通常最多丢失约 1 秒数据 适中
no 由操作系统决定何时刷盘 最低,可能丢大量数据 最好

生产环境推荐使用everysec,兼顾安全性和性能。

AOF 重写

AOF 有个明显缺点:文件体积大

同一个 key 写 100 次,AOF 就记 100 行,但实际只有最后一次有效。

Redis 提供了 BGREWRITEAOF 命令来重写 AOF 文件,用最少命令还原相同的数据状态。

比如上面的例子, 重写后只保留最终状态对应的写命令,例如:

plain 复制代码
SET name jack
SET number 666

只保留最终结果,大幅压缩文件体积。

可以通过两个条件自动触发重写:

  1. 体积增长比例:当前 AOF 文件比上一次重写后的文件增长超过设定百分比(默认 100%)就触发。
  2. 绝对体积阈值:AOF 文件超过设定大小(默认 64MB)就触发。

RDB vs AOF:怎么选?

维度 RDB AOF
持久化方式 整份内存快照 逐条记录写命令
数据完整性 两次备份之间可能丢数据 通常最多丢失约 1 秒数据
文件大小 小(二进制压缩) 大(文本命令日志)
恢复速度 慢(文件大)
默认恢复顺序 较低 较高(开启 AOF 时优先加载)
资源占用 fork 时占用较多 CPU 和内存 主要占用磁盘 I/O
适用场景 可容忍数分钟数据丢失 对数据安全性要求高

面试加分回答

如果面试官问"你们项目用哪个",推荐回答:

Redis 4.0 引入混合持久化(AOF rewrite 时结合 RDB 格式),进一步提升恢复速度。

AOF 保证日常数据安全性,RDB 作为后备,在 AOF 文件损坏时提供快速恢复能力。两者结合,既保数据安全,又保恢复效率。

这样回答既体现了理解深度,又展示了实际工程经验。

相关推荐
Conan在掘金1 小时前
鸿蒙 7.0 智能体框架 2.0:意图即服务根因——从 InsightIntentExecutor 到 HMAF 2.0 Skill 演进
后端
掘金者阿豪1 小时前
折腾电科金仓 Docker 部署的一晚上:角色登录失败、远程连接失败,这几个坑终于踩完了
后端
lichenyang4531 小时前
从图片创作到本地可复现的 AIGC 全栈闭环:AIGC Creative Studio 实践复盘
前端·后端
倒流时光三十年1 小时前
第三阶段 26 · highlight 高亮(返回命中片段)
后端·python·django
lpfasd1232 小时前
编程语言榜单变迁分析
开发语言·后端·scala
Shawn_Shawn2 小时前
google ADK VS Langchain-ai
后端·llm·agent
名字还没想好☜2 小时前
Go 用 bufio.Scanner 读大文件踩坑:默认 64KB 行上限、Buffer 扩容与按 Token 切分
开发语言·后端·golang·go
用户6083089290472 小时前
SpringBoot自定义注解校验
后端
董员外2 小时前
RAG 系统进化论(六):GraphRAG(基于知识图谱的 RAG),从相似文本走向实体关系
人工智能·后端·设计模式