Redis 持久化机制
概述
Redis 是一个内存数据库,为了保证数据的持久性,Redis 提供了两种主要的持久化方式:RDB(Redis Database)和 AOF(Append Only File)。从 Redis 7.0 开始,还引入了混合持久化模式,结合了两种方式的优点。
RDB 持久化
原理
RDB 持久化是通过创建数据集的时间点快照(snapshot)来实现的。Redis 会在指定的时间间隔内,将内存中的数据集快照写入磁盘,生成一个二进制文件(通常命名为 dump.rdb)。
工作流程:
- Redis 主进程 fork 出一个子进程
- 子进程将内存中的数据写入临时 RDB 文件
- 写入完成后,用临时文件替换旧的 RDB 文件
- 子进程退出
触发条件
- 自动触发: 根据配置的 save 规则
- 手动触发: 执行 SAVE 或 BGSAVE 命令
- 其他触发: 主从复制、SHUTDOWN 命令等
配置示例
# 在 900 秒内至少有 1 个键被修改时保存
save 900 1
# 在 300 秒内至少有 10 个键被修改时保存
save 300 10
# 在 60 秒内至少有 10000 个键被修改时保存
save 60 10000
# RDB 文件名
dbfilename dump.rdb
# RDB 文件保存目录
dir /var/lib/redis
优点
- 紧凑性: RDB 文件是一个紧凑的二进制文件,占用空间小
- 恢复速度快: 相比 AOF,RDB 文件恢复数据速度更快
- 适合备份: 单个文件便于备份和传输
- 性能影响小: 主进程不参与 I/O 操作,对性能影响较小
缺点
- 数据丢失风险: 在两次快照之间的数据可能丢失
- fork 开销: 数据量大时,fork 子进程可能耗时较长
- 不适合实时性要求高的场景
AOF 持久化
原理
AOF(Append Only File)持久化通过记录服务器执行的所有写操作命令来实现。Redis 会将每个写命令追加到 AOF 文件的末尾,重启时通过重新执行这些命令来恢复数据。
工作流程:
- 客户端发送写命令
- Redis 执行命令并将结果存储到内存
- 将命令追加到 AOF 缓冲区
- 根据同步策略将缓冲区内容写入 AOF 文件
同步策略
# 每次写操作都同步到磁盘(最安全,性能最差)
appendfsync always
# 每秒同步一次(默认,平衡安全性和性能)
appendfsync everysec
# 由操作系统决定何时同步(性能最好,安全性最差)
appendfsync no
AOF 重写
随着时间推移,AOF 文件会越来越大。Redis 提供 AOF 重写机制来压缩文件大小:
# 启用 AOF
appendonly yes
# AOF 文件名
appendfilename "appendonly.aof"
# 自动重写条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
优点
- 数据安全性高: 根据同步策略,最多丢失 1 秒的数据
- 文件可读: AOF 文件是文本格式,便于理解和修复
- 增量备份: 支持增量备份
- 自动修复: 提供 redis-check-aof 工具修复损坏的文件
缺点
- 文件体积大: 相同数据集,AOF 文件通常比 RDB 文件大
- 恢复速度慢: 需要重新执行所有命令
- 性能开销: 每次写操作都需要记录日志
Redis 7.0 混合持久化模式
概述
Redis 7.0 引入了混合持久化模式,结合了 RDB 和 AOF 的优点。在 AOF 重写时,Redis 会将当前内存中的数据以 RDB 格式写入 AOF 文件的开头,然后将重写期间的增量命令以 AOF 格式追加到文件末尾。
配置
# 启用混合持久化(Redis 4.0+ 支持,7.0 优化)
aof-use-rdb-preamble yes
# 同时启用 RDB 和 AOF
save 900 1
appendonly yes
appendfsync everysec
文件目录结构
/var/lib/redis/
├── dump.rdb # RDB 快照文件
├── appendonly.aof # AOF 日志文件(混合格式)
├── appendonly.aof.1.base.rdb # AOF 重写时的 RDB 基础文件
├── appendonly.aof.1.incr.aof # AOF 重写时的增量文件
└── appendonly.aof.manifest # AOF 文件清单
Redis 7.0 多部分 AOF
Redis 7.0 引入了多部分 AOF 架构:
- Base AOF: 包含重写时的完整数据快照(RDB 格式)
- Incremental AOF: 包含重写后的增量命令
- Manifest 文件: 记录 AOF 文件的元信息
工作原理
- 正常运行: 写命令同时记录到 AOF 文件
- 触发重写: 创建新的 Base AOF(RDB 格式)+ Incremental AOF
- 重写完成: 更新 Manifest 文件,切换到新的 AOF 文件组
- 数据恢复: 先加载 Base AOF,再重放 Incremental AOF
优势
- 快速恢复: Base AOF 采用 RDB 格式,加载速度快
- 数据安全: 保持 AOF 的数据安全特性
- 文件管理: 多文件架构便于管理和维护
- 减少重写开销: 重写过程更加高效
混合持久化是否还需要RDB?
答案:通常不需要单独的RDB
在混合持久化模式下,AOF重写时会生成RDB格式的Base文件,这已经包含了完整的数据快照。因此:
- 冗余性考虑: 单独的RDB文件与Base AOF功能重复
- 存储优化: 避免重复存储相同数据
- 维护简化: 减少文件管理复杂度
例外情况:
- 备份需求: 如果需要定期的独立备份文件
- 兼容性: 某些监控工具依赖RDB文件
- 迁移场景: 数据迁移时RDB文件更便于传输
混合持久化详细流程
流程图
flowchart TD
A[Redis启动] --> B[加载现有数据]
B --> C{检查文件类型}
C -->|有Manifest文件| D[多部分AOF模式]
C -->|只有AOF文件| E[传统AOF模式]
C -->|只有RDB文件| F[RDB模式]
D --> G[读取Manifest]
G --> H[加载Base AOF]
H --> I[加载Incremental AOF]
I --> J[数据恢复完成]
J --> K[正常运行]
K --> L[写命令执行]
L --> M[记录到当前AOF]
M --> N{触发重写条件?}
N -->|否| L
N -->|是| O[开始AOF重写]
O --> P[Fork子进程]
P --> Q[子进程生成新Base AOF<br/>RDB格式]
P --> R[主进程继续服务<br/>记录到Incremental AOF]
Q --> S[Base AOF生成完成]
R --> T[Incremental AOF记录]
S --> U[更新Manifest文件]
T --> U
U --> V[切换到新AOF文件组]
V --> W[清理旧文件]
W --> K
详细步骤说明
1. 启动阶段
# 数据恢复优先级
1. 检查appendonly.aof.manifest文件
2. 如果存在,按Manifest加载多部分AOF
3. 如果不存在,检查appendonly.aof
4. 最后检查dump.rdb
2. 正常运行阶段
# 写操作流程
Client --> Redis Server --> Memory Update --> AOF Buffer --> Disk Sync
\--> Replication Buffer (if slaves exist)
3. AOF重写触发
# 自动触发条件
- AOF文件大小超过auto-aof-rewrite-min-size
- AOF文件增长比例超过auto-aof-rewrite-percentage
# 手动触发
BGREWRITEAOF
4. 混合重写过程
# 步骤详解
1. 主进程fork子进程
2. 子进程开始生成新的Base AOF(RDB格式)
3. 主进程继续处理客户端请求
4. 重写期间的新命令记录到Incremental AOF
5. 子进程完成Base AOF生成
6. 主进程更新Manifest文件
7. 原子性切换到新的AOF文件组
8. 清理旧的AOF文件
5. 文件结构变化
# 重写前
/var/lib/redis/
├── appendonly.aof.1.base.rdb
├── appendonly.aof.1.incr.aof
└── appendonly.aof.manifest
# 重写中
/var/lib/redis/
├── appendonly.aof.1.base.rdb # 旧文件
├── appendonly.aof.1.incr.aof # 旧文件
├── appendonly.aof.2.base.rdb # 新生成
├── appendonly.aof.2.incr.aof # 新增量
└── appendonly.aof.manifest # 更新中
# 重写后
/var/lib/redis/
├── appendonly.aof.2.base.rdb # 新基础文件
├── appendonly.aof.2.incr.aof # 新增量文件
└── appendonly.aof.manifest # 已更新
配置示例
推荐的混合持久化配置
# redis.conf 混合持久化最佳配置
# 禁用RDB(混合模式下不需要)
# save "" # 注释掉所有save配置
# 或者设置为空
save ""
# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 混合持久化(关键配置)
aof-use-rdb-preamble yes
# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 数据目录
dir /var/lib/redis
# 可选:如果需要独立RDB备份
# save 3600 1 # 每小时至少1个变更时备份
兼容性配置(保留RDB)
# 如果需要同时保留RDB(用于备份或兼容性)
# RDB 配置(降低频率)
save 3600 1 # 每小时备份一次
save 86400 100 # 每天备份一次(如果有100个变更)
dbfilename dump.rdb
# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 混合持久化
aof-use-rdb-preamble yes
# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 数据目录
dir /var/lib/redis
持久化策略选择
场景建议
- 高可用性要求: 使用 AOF + 混合持久化
- 性能优先: 使用 RDB
- 平衡方案: 使用混合持久化模式
- 备份需求: RDB + AOF 双重保障
监控和维护
# 查看持久化状态
INFO persistence
# 手动触发 RDB 保存
BGSAVE
# 手动触发 AOF 重写
BGREWRITEAOF
# 检查 AOF 文件
redis-check-aof --fix appendonly.aof
总结
Redis 7.0 的混合持久化模式通过结合 RDB 的快速恢复和 AOF 的数据安全特性,为用户提供了更好的持久化解决方案。多部分 AOF 架构进一步优化了文件管理和重写性能,是现代 Redis 部署的推荐配置。