写在前面
Redis作为内存数据库,数据存储在内存中,一旦服务器重启或宕机,内存中的数据就会丢失。持久化机制是Redis保证数据安全性的核心能力,也是面试中的高频考点。今天我们就来深入理解Redis的两种持久化方式:RDB和AOF。

文章目录
-
- 写在前面
- 一、为什么需要持久化?
- 二、RDB持久化原理
-
- [2.1 什么是RDB?](#2.1 什么是RDB?)
- [2.2 RDB触发机制](#2.2 RDB触发机制)
- [2.3 RDB执行流程](#2.3 RDB执行流程)
- [2.4 RDB的优缺点](#2.4 RDB的优缺点)
- 三、AOF持久化原理
-
- [3.1 什么是AOF?](#3.1 什么是AOF?)
- [3.2 AOF配置](#3.2 AOF配置)
- [3.3 AOF重写机制](#3.3 AOF重写机制)
- [3.4 AOF的优缺点](#3.4 AOF的优缺点)
- [四、RDB vs AOF对比](#四、RDB vs AOF对比)
- 五、混合持久化
- 六、踩坑提醒
- 七、面试高频考点
- 八、参考资料
- 九、互动话题
一、为什么需要持久化?
实际场景:某电商平台的购物车数据存储在Redis中,某天服务器因断电重启,导致数万用户的购物车数据全部丢失,造成严重的用户体验问题和商业损失。
Redis是一个基于内存的高性能键值数据库,内存中的数据具有易失性。当Redis服务重启或服务器宕机时,内存中的所有数据都会丢失。为了解决这个问题,Redis提供了持久化机制,将内存中的数据保存到磁盘,在服务重启后可以从磁盘恢复数据。
持久化的核心目标:
- 数据安全性:防止数据丢失
- 服务可用性:快速恢复服务
- 灾难恢复:应对硬件故障
二、RDB持久化原理
2.1 什么是RDB?
RDB(Redis Database)是Redis的默认持久化方式,它将某一时刻的内存数据生成快照(Snapshot),以二进制文件的形式保存到磁盘。RDB文件是一个经过压缩的二进制文件,默认文件名为dump.rdb。
2.2 RDB触发机制
RDB持久化可以通过以下方式触发:
1. 自动触发(配置文件)
conf
# redis.conf 配置
save 900 1 # 900秒内至少有1个key变化
save 300 10 # 300秒内至少有10个key变化
save 60 10000 # 60秒内至少有10000个key变化
2. 手动触发
redis
# 阻塞式创建RDB(生产环境慎用)
SAVE
# 非阻塞式创建RDB(推荐)
BGSAVE
3. 特殊触发场景
- 执行
FLUSHALL命令 - 执行
SHUTDOWN命令(如果没有开启AOF) - 主从复制时,主节点自动执行
BGSAVE
2.3 RDB执行流程
经验之谈 :理解RDB的执行流程对于排查生产问题非常重要,特别是
fork操作的影响。
RDB持久化的核心流程如下:
-
Redis父进程执行
fork()创建子进程 -
子进程将内存数据写入临时RDB文件
-
子进程写完后,用临时文件替换原RDB文件
-
子进程退出,父进程继续处理请求
┌─────────────────┐
│ Redis主进程 │
└────────┬────────┘
│ fork()
▼
┌─────────────────┐
│ 子进程 │ ──► 写入临时RDB文件 ──► 替换原RDB文件
└─────────────────┘
2.4 RDB的优缺点
| 优点 | 缺点 |
|---|---|
| 文件紧凑,适合备份和灾难恢复 | 无法做到实时持久化,可能丢失数据 |
| 恢复速度快,直接加载到内存 | fork操作在数据量大时可能阻塞 |
| 对性能影响小,子进程负责写入 | RDB文件格式可能不兼容不同版本 |
| 适合冷备份、全量复制场景 | 不适合实时性要求高的场景 |
三、AOF持久化原理
3.1 什么是AOF?
AOF(Append Only File)以日志的形式记录Redis执行的每一个写命令,追加到AOF文件末尾。Redis重启时,重新执行AOF文件中的命令来恢复数据。
3.2 AOF配置
conf
# redis.conf 配置
appendonly yes # 开启AOF
appendfilename "appendonly.aof" # AOF文件名
appendfsync everysec # 同步策略
AOF同步策略对比:
| 策略 | 说明 | 性能 | 数据安全性 |
|---|---|---|---|
always |
每个写命令都同步 | 最差 | 最高(最多丢1条命令) |
everysec |
每秒同步一次 | 较好 | 较高(最多丢1秒数据) |
no |
由操作系统决定 | 最好 | 最差(可能丢30秒数据) |
3.3 AOF重写机制
踩坑提醒:AOF文件会随着写命令的增加而不断增大,需要定期进行重写压缩。但AOF重写过程中可能会造成短暂的阻塞。
AOF重写的目的:压缩AOF文件体积,去除冗余命令。
重写原理:
- Redis执行
fork()创建子进程 - 子进程基于当前内存数据生成新的AOF文件
- 父进程同时将新写命令追加到AOF重写缓冲区
- 子进程完成后,父进程将重写缓冲区的命令追加到新AOF文件
- 用新AOF文件原子性地替换旧文件
redis
# 手动触发AOF重写
BGREWRITEAOF
# 自动触发配置
auto-aof-rewrite-min-size 64mb # AOF文件最小大小
auto-aof-rewrite-percentage 100 # 文件大小增长百分比
3.4 AOF的优缺点
| 优点 | 缺点 |
|---|---|
| 数据安全性高,最多丢失1秒数据 | AOF文件体积比RDB大 |
| 可读性好,便于分析和修复 | 恢复速度比RDB慢 |
| 支持重写机制压缩文件 | 写入性能略低于RDB |
| 适合实时性要求高的场景 | 大量小命令会影响性能 |
四、RDB vs AOF对比
| 对比项 | RDB | AOF |
|---|---|---|
| 持久化方式 | 快照(二进制) | 日志追加(文本) |
| 数据安全性 | 较低(可能丢失几分钟数据) | 较高(最多丢失1秒数据) |
| 文件大小 | 小(压缩二进制) | 大(文本命令) |
| 恢复速度 | 快 | 慢 |
| 系统资源消耗 | 低(fork时有开销) | 较高(持续写入) |
| 适用场景 | 备份、灾难恢复 | 数据安全性要求高 |
| 优先级 | 低 | 高(同时开启时优先加载AOF) |
五、混合持久化
Redis 4.0引入了混合持久化,结合RDB和AOF的优点:
conf
# 开启混合持久化
aof-use-rdb-preamble yes
混合持久化原理:
- AOF重写时,先写入RDB格式的快照数据
- 再追加AOF格式的增量命令
- 恢复时,先加载RDB部分,再执行AOF命令
优势:
- 恢复速度快(RDB部分)
- 数据安全性高(AOF部分)
- 文件体积适中
六、踩坑提醒
踩坑提醒:AOF重写阻塞问题
问题描述:
AOF重写时,父进程需要将重写期间的写命令追加到AOF重写缓冲区。当子进程完成重写后,父进程需要将缓冲区的命令同步到新AOF文件,这个过程可能会阻塞主线程。
解决方案:
- 合理配置重写阈值,避免频繁重写
- 在业务低峰期手动触发重写
- 监控AOF文件大小,提前预警
conf
# 调整重写触发条件
auto-aof-rewrite-min-size 128mb
auto-aof-rewrite-percentage 100
踩坑提醒:RDB fork阻塞
问题描述:
当Redis内存数据量很大时(如10GB以上),fork操作会耗时较长,期间Redis无法处理请求。
解决方案:
- 控制单实例内存大小(建议不超过10GB)
- 使用物理机或支持COW的虚拟化平台
- 监控
latest_fork_usec指标
七、面试高频考点
考点1:RDB和AOF的区别?
答案:
- 持久化方式:RDB是快照二进制文件,AOF是命令日志文本文件
- 数据安全性:RDB可能丢失几分钟数据,AOF最多丢失1秒数据
- 恢复速度:RDB快,AOF慢
- 文件大小:RDB小,AOF大
- 资源消耗:RDB在fork时有开销,AOF持续有写入开销
考点2:如何选择持久化方案?
答案:
| 场景 | 推荐方案 |
|---|---|
| 只追求性能,不关心数据丢失 | 关闭持久化 |
| 允许分钟级丢失,追求恢复速度 | 仅RDB |
| 数据安全性要求高 | 仅AOF(everysec) |
| 综合考虑 | 混合持久化(推荐) |
考点3:RDB的save配置如何理解?
答案:
save <秒数> <变化数>表示在指定秒数内,至少有指定数量的key发生变化时触发RDB。例如save 60 10000表示60秒内至少有10000个key变化才触发。可以配置多个条件,满足任一条件即触发。
考点4:AOF重写时会影响正常请求吗?
答案:
AOF重写过程中:
- 子进程负责重写,不影响主进程处理请求
- 主进程将重写期间的新写命令追加到AOF重写缓冲区
- 子进程完成后,主进程需要将缓冲区命令同步到新文件,这个过程会短暂阻塞
- 合理配置可以减少重写频率,降低影响
八、参考资料
九、互动话题
- 你的生产环境使用的是哪种持久化方案?遇到过什么问题?
- 在数据量达到50GB的情况下,你会如何优化持久化配置?
- 如何设计一个监控方案,及时发现持久化相关的性能问题?
欢迎在评论区分享你的经验和见解!
下一期预告:Day7 - Redis事务与Lua脚本,敬请期待!