在讲核心内容前,先定一个前提 :Redis是纯内存数据库 ,数据都存在内存里,一旦Redis重启/服务器断电,内存数据会直接消失。持久化就是Redis把内存数据"存到硬盘文件里"的操作,目的是重启后能恢复数据,而AOF和RDB就是Redis实现持久化的两种核心方式,就像我们平时保存文件的两种不同方法。
一、先搞懂:Redis的RDB持久化(快照式持久化)
1. 给内存数据"拍张完整照片"
把Redis的内存想象成你的手机相册 ,RDB就相当于定时给相册拍一张完整的截图,把截图保存到硬盘里。
- 拍照的瞬间,相册里有多少照片、每张照片在哪,截图里都完整记录;
- 拍照后你再往相册里加/删照片,不会影响之前的截图;
- 要是手机丢了(Redis重启/断电),用最近的那张截图(RDB文件),就能恢复出拍照瞬间的所有照片(数据)。
2. 官方定义
RDB是快照式持久化 ,Redis会在指定的时间条件下,将当前内存中的所有数据 以二进制压缩格式生成一个单一的RDB文件,恢复时直接加载这个文件到内存即可。
3. 核心特点
- 优点:文件是二进制压缩的,体积极小 ;恢复数据时直接加载整文件,速度极快(不用执行命令,直接读数据);
- 缺点:只有"拍照瞬间"的数据,拍照后到崩溃前的新数据会丢失(比如5分钟拍一次照,刚拍过照1分钟就崩了,这1分钟的数据没了);
二、再搞懂:Redis的AOF持久化(日志式持久化)
1. 通俗理解:给所有写操作"记流水账"
还是把Redis内存想象成手机相册,AOF就相当于给你的每一次相册操作记流水账 ,把"新增1张照片""删除第3张照片""修改照片名称"这些所有写操作,按顺序一字不差地写到硬盘的日志文件里。
- 你做的每一个修改操作,都会立刻/定时记到流水账里(只记写操作,查操作不记);
- 流水账是追加写(只在文件末尾加内容,从不改之前的记录),不会丢历史;
- 要是手机丢了,Redis重启后会从头执行流水账里的所有命令,一步步还原出最新的相册状态(数据)。
2. 官方定义(通俗翻译)
AOF是日志式持久化 ,Redis会把所有对数据的写命令 (set/hset/del等)按执行顺序以明文文本格式追加到AOF文件中,恢复时通过"重放"这些命令重建内存数据。
3. 关键补充:AOF重写(解决流水账太长的问题)
如果一直记流水账,文件会越来越大(比如你反复修改一个key,流水账会记几十次修改命令,但其实只需要最后一次的结果)。
Redis的AOF重写 就是:Redis会根据当前内存的最新数据,重新生成一个最简的AOF文件(只保留能还原当前数据的必要命令,删掉冗余命令),比如反复修改key的命令,只留最后一次set,相当于"把厚厚的流水账精简成一页核心账单",不丢失数据但大幅减小文件体积。
4. 核心特点
- 优点:按命令记录,数据丢失极少(可配置每秒/每次操作记日志);文件是明文命令,能直接看懂、甚至手动修改(比如删了错的del命令);
- 缺点:明文文本格式,文件体积比RDB大很多 ;恢复时要逐行执行命令,速度比RDB慢;
三、实操:修改Redis配置+生成文件+看直观区别
Redis的配置文件默认叫redis.conf(Linux下默认在/etc/redis/,Windows下和Redis启动文件同目录),实操前先停掉Redis服务 (避免配置修改不生效),Linux停服务命令:systemctl stop redis。
前置:Redis默认配置
- RDB:默认开启,不用改配置就能生成RDB文件;
- AOF:默认关闭,需要手动改配置开启。
步骤1:修改RDB核心配置(redis.conf里找对应配置,改完保存)
conf
# 1. 触发RDB的条件:【时间窗口】内有【指定数量的写操作】,可配多个,注释掉就是关闭自动RDB
# 意思:900秒(15分钟)内至少1个写操作,就自动生成RDB;300秒(5分钟)内至少10个;60秒内至少1000个
save 900 1
save 300 10
save 60 1000
# 2. RDB文件的名字(默认dump.rdb,可自定义,后缀建议保留.rdb)
dbfilename dump.rdb
# 3. RDB/AOF文件的存储目录(所有持久化文件都放这里,必须是绝对路径,Linux默认./表示Redis启动目录)
dir /var/lib/redis # 建议改绝对路径,方便找,Linux下这个目录是Redis默认数据目录
步骤2:修改AOF核心配置(开启AOF+配置关键参数)
conf
# 1. 开启AOF(默认no,改成yes就是开启,这是AOF的核心开关)
appendonly yes
# 2. AOF文件的名字(默认appendonly.aof,可自定义,后缀建议保留.aof)
appendfilename appendonly.aof
# 3. 【关键】AOF日志的刷盘策略(决定数据丢失的多少,选everysec就够了,Redis默认)
# 三个选项:
# always:每执行一个写命令,立刻把日志写到硬盘,数据几乎不丢,但性能最差(频繁写硬盘)
# everysec:每秒把日志写到硬盘一次,折中方案(最多丢1秒数据),性能和安全性平衡
# no:把日志交给操作系统管理,操作系统什么时候写硬盘Redis不管,性能最好,丢数据最多
appendfsync everysec
# 4. AOF重写的自动触发条件(默认开启,不用改)
# 意思:AOF文件体积比上次重写后增大100%,且文件体积至少64M时,自动触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
步骤3:重启Redis+生成持久化文件
-
重启Redis服务:
systemctl start redis(Linux),Windows直接双击Redis启动文件; -
连接Redis客户端:
redis-cli; -
执行几个写操作(触发RDB+生成AOF日志):
redisset name "张三" hset user id 1 age 20 del test # 随便加个删操作,看AOF会不会记录 -
手动触发RDB生成 (不用等定时条件,立刻生成):在Redis客户端执行
bgsave(后台生成,不阻塞Redis); -
手动触发AOF重写 (可选,看精简后的AOF):在Redis客户端执行
bgrewriteaof(后台重写,不阻塞Redis)。
步骤4:找到文件+看直观区别
先查Redis持久化文件的存储目录(对应配置里的dir),执行redis-cli config get dir就能看到绝对路径,比如结果是/var/lib/redis,进入这个目录:cd /var/lib/redis,然后用ls就能看到生成的文件:dump.rdb和appendonly.aof。
用Linux命令看文件内容,区别一眼看穿
- 查看RDB文件:
cat dump.rdb- 结果:全是乱码(二进制压缩格式,人类看不懂);
- 用
ls -lh看体积:极小(比如执行了3个写操作,文件大小可能只有几十字节)。
- 查看AOF文件:
cat appendonly.aof- 结果:明文Redis命令 ,人类能直接看懂,格式是Redis的协议格式(核心命令能一眼识别),比如能看到
set name 张三、hset user id 1、del test这些操作; - 用
ls -lh看体积:比RDB大很多(比如同样3个写操作,AOF文件可能有几百字节)。
- 结果:明文Redis命令 ,人类能直接看懂,格式是Redis的协议格式(核心命令能一眼识别),比如能看到
核心文件区别总结(直观版)
| 特性 | RDB文件 | AOF文件 |
|---|---|---|
| 格式 | 二进制压缩 | 明文文本(Redis协议) |
| 体积 | 极小 | 较大(重写后会变小) |
| 可读性 | 人类完全看不懂 | 人类能看懂、可手动修改 |
| 记录内容 | 某一时刻的全量数据 | 所有写操作的顺序日志 |
四、和MySQL的binlog/redolog对比
先明确一个前提:MySQL是磁盘数据库 (数据默认存在硬盘),但为了速度,会把常用数据加载到内存,所以MySQL的日志(binlog/redolog)和Redis的持久化文件设计目的不同,但核心思想有相似之处,先通俗讲清楚MySQL的binlog和redolog,再对比。
先搞懂:MySQL的binlog和redolog
把MySQL的硬盘数据想象成公司的纸质账本 ,内存想象成会计的电脑账本 ,会计做账的规则是:先改电脑账本,再定期同步到纸质账本(因为改电脑快,改纸质慢)。
-
redolog(重做日志):InnoDB引擎独有,相当于会计的【临时便签】
- 作用:防止会计改了电脑账本,还没同步到纸质账本,突然停电(MySQL崩溃),电脑数据丢了,纸质账本还是旧的。会计每改一次电脑账本,就立刻在便签上记一句"改了哪一页纸的哪一行",就算停电,恢复后看便签,就能把纸质账本改成最新的;
- 核心特点:循环写 (便签纸就那么大,写满了就从头覆盖旧的)、物理日志 (记录"硬盘的哪个数据页改了什么",和硬盘物理存储关联)、保证事务持久性(MySQL的ACID中D的核心);
- 只记"修改操作",不记查询,且只保留最近的修改(循环覆盖)。
-
binlog(归档日志):MySQL服务器层日志,所有引擎都支持,相当于公司的【正式记账流水】
- 作用:记录公司所有的"记账操作",不管是改、删、加,都按顺序记下来,永久保存(不会自动覆盖),用于数据恢复 和主从复制(从库跟着主库的binlog执行相同操作,保持数据一致);
- 核心特点:追加写 (只在流水本末尾加内容,从不改之前的记录)、逻辑日志 (记录"做了什么操作",比如
update user set age=20 where id=1,和硬盘物理存储无关)、全量写操作记录;
核心对比:Redis(AOF/RDB) vs MySQL(binlog/redolog)
1. 最核心的对应关系(记死这个,永远不混)
- Redis RDB ≈ MySQL的【全量备份】(比如mysqldump/xtrabackup):都不是日志,是某一时刻的全量数据快照,恢复快,体积小,丢数据多;
- Redis AOF ≈ MySQL的binlog :都是追加写的逻辑日志,记录所有写操作,用于数据恢复,体积大,恢复慢,丢数据少;
2. 关键区别:Redis没有"类似MySQL redolog"的东西
原因很简单:设计思想不同
- MySQL用的是WAL(写前日志) :先写redolog(便签),再改内存,最后定期同步到硬盘,核心是保证崩溃后数据不丢(即使内存数据丢了,用redolog恢复);
- Redis是内存优先 :先改内存(操作立刻返回成功),再异步把数据/命令写到硬盘(RDB/AOF),核心是保证性能(Redis的核心优势就是快),所以Redis不需要redolog这种"崩溃恢复临时日志"------就算持久化还没写,内存数据丢了,最多丢一点最新数据,这是Redis为了性能做的取舍。
3. 一张表讲清所有核心区别
| 特性 | Redis RDB | Redis AOF | MySQL redolog | MySQL binlog |
|---|---|---|---|---|
| 设计目的 | 全量数据备份 | 记录所有写操作 | 崩溃恢复 | 归档/主从/恢复 |
| 写入方式 | 定时覆盖生成 | 追加写 | 循环写 | 追加写 |
| 日志类型 | 非日志(快照) | 逻辑日志 | 物理日志 | 逻辑日志 |
| 引擎依赖 | Redis通用 | Redis通用 | 仅InnoDB | MySQL所有引擎 |
| 可读性 | 无 | 有(明文) | 无(二进制) | 有(可解析) |
| 数据丢失 | 较多(快照间隔) | 极少(秒级/实时) | 几乎无 | 极少 |
五、和Git的log文件对比
Git是版本控制系统,核心是记录项目的所有修改,支持版本回滚、恢复历史,这和Redis持久化"记录数据修改、恢复数据"的核心思想高度相似,用Git做对比,程序员能一秒懂AOF和RDB的本质区别。
先定一个通用比喻:
- Redis内存 ≈ Git的工作区(你正在修改的代码,还没提交);
- Redis持久化文件(RDB+AOF) ≈ Git的本地仓库(所有提交记录和文件快照,存在硬盘,不会丢);
- Redis的写操作 ≈ Git的工作区修改(增删改代码);
核心对应关系(全程用Git操作比喻,一看就会)
-
Redis RDB ≈ Git的【全量快照/打Tag/打包项目】
- Git打Tag:比如你在项目v1.0版本打一个tag,就是给这个版本的所有代码拍了一张完整快照,不管后续怎么改,都能通过tag恢复到v1.0;
- Git打包:把当前项目的所有文件打成一个zip包,就是全量快照,和RDB把内存所有数据打成二进制包完全一样;
- 特点:快照文件体积小,恢复快,只记录某一时刻的状态,没有历史修改记录。
-
Redis AOF ≈ Git的【commit log(提交日志)】
- 你在Git里每执行一次
git commit -m "修改了XX功能",就是把工作区的修改按顺序记录到commit log里,和AOF记录每一个写操作完全一样; - Git的
git log能看到所有提交记录(按时间顺序),Redis的AOF文件能看到所有写操作记录(按时间顺序); - Git支持
git reset --hard 提交ID回滚到任意版本,Redis支持修改AOF文件删去后续命令,重放后恢复到任意时刻的数- 据,核心逻辑完全一致; - 特点:追加写,记录所有历史修改,体积随时间增大,能恢复到任意历史状态。
- 你在Git里每执行一次
-
Redis AOF重写 ≈ Git的【合并提交(git rebase -i)】
- 你在Git里可能会有很多次小提交(比如"修复一个小bug""改个变量名"),用
git rebase -i可以把这些小提交合并成一个大提交,日志会变简洁,体积变小; - Redis的AOF重写就是把多次冗余的写命令合并成最简命令,AOF文件体积变小,核心目的都是精简日志,不丢失历史数据。
- 你在Git里可能会有很多次小提交(比如"修复一个小bug""改个变量名"),用
-
Git的reflog ≈ Redis AOF重写前的原文件
- Git的reflog会记录所有操作(包括合并提交、回滚),就算合并了提交,也能通过reflog恢复到合并前的状态;
- Redis的AOF重写时,会先保留原AOF文件,重写完成后再替换,就算重写出错,也能通过原文件恢复数据,逻辑一致。
核心总结:Git和Redis持久化的相同思想
两者的核心都是**"快照+日志"的组合思路**:
- Git用「tag/全量快照」做快速恢复,用「commit log」做细粒度历史记录;
- Redis用「RDB快照」做快速恢复,用「AOF日志」做细粒度数据保护;
- 实际使用中,Redis推荐AOF+RDB同时开启 ,Git推荐定期打Tag+频繁commit,本质都是"用快照保速度,用日志保数据"。
六、总结
1. AOF和RDB的核心区别(最核心)
- RDB是记结果:记录某一时刻的全量数据,二进制压缩,小而快,丢数据多;
- AOF是记过程:记录所有写操作的顺序,明文文本,大而慢,丢数据少;
2. 配置&文件实操关键
- RDB默认开启,核心配置是
save(触发条件)、dbfilename(文件名)、dir(存储目录); - AOF需要开
appendonly yes,核心配置是appendfsync(刷盘策略)、appendfilename(文件名); - RDB文件是乱码二进制,AOF是明文命令,体积差距大。
3. 和MySQL日志的核心对应
- RDB ≈ MySQL全量备份,AOF ≈ MySQL binlog;
- Redis无类似redolog的组件,因为Redis是内存优先,MySQL是WAL写前日志(崩溃恢复优先)。
4. 和Git log的核心对应
- RDB ≈ Git Tag/全量快照,AOF ≈ Git commit log;
- AOF重写 ≈ Git合并提交,核心都是精简日志、保留核心数据。
5. 实际使用建议
Redis生产环境推荐AOF+RDB同时开启:重启时先加载AOF文件(数据最新),用RDB做定期全量备份(方便快速恢复),兼顾数据安全性和恢复速度。