Redis里RDB和AOF的区别

Redis 里 RDB 和 AOF 的区别

学 Redis 持久化的时候,RDBAOF 是很容易混的两个点。

它们的目的都一样:让 Redis 重启后还能恢复数据

但是它们保存数据的思路完全不一样:

  • RDB:保存某一时刻的数据结果
  • AOF:保存每一次写操作的命令过程

说白了:

RDB 像"拍照片",AOF 像"记流水账"。

一、先用一张图看整体区别

Redis 内存数据
RDB:生成快照文件 dump.rdb
AOF:追加写命令 appendonly.aof
重启时直接加载快照结果
重启时重新执行写命令

这张图就能看出核心区别:

  • RDB 保存的是内存数据的最终状态
  • AOF 保存的是修改数据的命令记录

二、RDB 是什么

RDB 可以理解成 Redis 给当前内存数据做了一次"快照"。

比如我执行了:

redis 复制代码
SET name a
SET name b
SET name c

如果这时候 Redis 生成一次 RDB 文件,它不会关心你前面改了几次,只关心当前最终结果。

最终保存的效果更像是:

text 复制代码
name = c

这里要记住:RDB 不记录修改过程,只记录某一时刻的最终数据。

三、RDB 的底层大概怎么做

RDB 持久化不是主进程自己慢慢把数据写完再继续干活。

它通常会通过 fork 创建一个子进程,让子进程负责把内存数据写成 RDB 文件。

大概流程是这样:
Redis 主进程
触发 RDB 保存
fork 出子进程
子进程读取当前内存数据
写入临时 RDB 文件
替换旧的 dump.rdb
主进程继续处理客户端请求

这里有一个底层点要知道:

fork 之后,子进程看到的是 fork 那一刻的数据状态。后面主进程继续处理新的写命令,操作系统会通过写时复制机制处理内存变化。

不用把这个机制背得特别深,先理解成:

RDB 保存的是 fork 那一刻的快照,不是实时不断变化的过程。

四、AOF 是什么

AOF 全称是 Append Only File,可以理解成"追加日志文件"。

Redis 每执行一条会修改数据的命令,就把这条命令追加到 AOF 文件里。

比如:

redis 复制代码
SET name a
SET name b
SET name c

AOF 一开始记录的通常就是:

redis 复制代码
SET name a
SET name b
SET name c

也就是说,AOF 保存的是:

你是怎么一步一步把数据改成现在这样的。

五、AOF 的底层大概怎么写

AOF 不是简单一句"写到文件"就结束了。

它中间还有一个比较重要的问题:什么时候真正刷到磁盘?

大概流程可以这样看:
客户端发送写命令
Redis 执行命令,修改内存
把写命令追加到 AOF 缓冲区
write 写入操作系统缓存
fsync 按策略刷到磁盘
appendonly.aof 文件

这里有个关键配置:

conf 复制代码
appendfsync always
appendfsync everysec
appendfsync no

这三个配置的意思是:

  • always:每次写命令都刷盘,最安全,但性能最差
  • everysec:每秒刷一次盘,比较常用,最多可能丢 1 秒数据
  • no:交给操作系统决定什么时候刷盘,性能好,但风险更大

一般学习和实际使用里,最常见的是:

conf 复制代码
appendfsync everysec

六、用一个例子真正分清楚

比如我执行下面这些命令:

redis 复制代码
SET k1 1
INCR k1
INCR k1
DEL k1
SET k2 hello

如果是 AOF

AOF 关心的是过程,所以它可能记录:

redis 复制代码
SET k1 1
INCR k1
INCR k1
DEL k1
SET k2 hello

如果是 RDB

RDB 关心的是结果。

最后 k1 已经被删了,只剩:

text 复制代码
k2 = hello

所以可以发现:

  • AOF 会知道 k1 曾经经历过什么
  • RDB 只知道最后 k1 已经不存在

七、AOF 重写又是什么

这里是另一个容易混的地方。

AOF 一直追加命令,文件会越来越大。

比如:

redis 复制代码
SET name a
SET name b
SET name c

如果一直保留这些命令,前两条其实已经没意义了,因为最后结果就是 name = c

所以 Redis 会进行 AOF 重写,把旧日志压缩成更短的新日志。
旧 AOF:SET name a

SET name b

SET name c
AOF 重写
新 AOF:SET name c

注意:

AOF 平时记录过程,AOF 重写后才会尽量整理成最终有效结果。

所以不能简单说"AOF 只保存最后结果"。

更准确的说法是:

  • 平时 AOF:记录每一次写操作
  • AOF 重写后:把没必要的旧操作压缩掉

八、Redis 重启时怎么恢复

Redis 重启时,如果有持久化文件,就会把数据恢复到内存里。

恢复流程可以这样理解:




Redis 启动
是否开启 AOF 并存在 AOF 文件?
优先加载 AOF
重新执行 AOF 里的写命令
恢复内存数据
是否存在 RDB 文件?
加载 RDB 快照
空数据启动

这里要记住:

如果同时开启了 RDB 和 AOF,Redis 通常会优先用 AOF 恢复,因为 AOF 往往数据更完整。

九、RDB 和 AOF 对比表

对比点 RDB AOF
保存内容 某一时刻的数据结果 每一次写操作命令
理解方式 拍快照 记日志
文件大小 通常较小 通常较大
恢复速度 通常较快 通常较慢
数据安全性 可能丢最近一次快照后的数据 一般丢失更少
适合场景 备份、快速恢复 尽量减少数据丢失

十、怎么记最简单

我觉得最容易记的方式就是三句话:

  • RDB:我现在有什么数据
  • AOF:我执行过哪些写命令
  • AOF 重写:把旧命令整理成更短的新命令

再压缩一下就是:

RDB 看结果,AOF 看过程。

十一、小结

RDB 的底层重点是:Redis 在某个时间点 fork 子进程,把当时的内存数据写成快照文件。

AOF 的底层重点是:Redis 执行写命令后,会把命令追加到 AOF 里,再根据刷盘策略写入磁盘。

所以最后总结一句:

RDB 记录某一刻的最终数据,AOF 记录数据变化的操作过程。

相关推荐
YJlio7 小时前
《Windows Internals》10.5.1 ETW 概述:看懂 Windows 的“事件高速公路”
java·windows·笔记·stm32·嵌入式硬件·学习·eclipse
budingxiaomoli8 小时前
SpringCloud概述
java·spring cloud·微服务
绿草在线8 小时前
基于SpringBoot4+Mybatis+Thymeleaf的用户管理系统开发实战
java·spring boot·thymeleaf
2601_949817928 小时前
nginx 代理 redis
运维·redis·nginx
鸟儿不吃草8 小时前
Android Java 自定义TextView点击取词,类似百度翻译的点击一段英文中的某个单词,可以显示点击了哪个单词
android·java·开发语言
梦梦代码精8 小时前
LikeShop 是怎么解决数据库瓶颈的?
java·数据库·低代码·php
.柒宇.8 小时前
AI 掘金头条项目-用户模块、收藏模块以及Redis和调用大模型实现
redis·python·fastapi·千问·qwen大模型
eRRA OFAG8 小时前
mysql之联合索引
java
薪火铺子8 小时前
CAS单点登录原理与实践
java·后端