RDB vs AOF 持久化
🔴 困难题目描述
解释 Redis 的 RDB 和 AOF 两种持久化方式的区别。如何选择合适的持久化策略?
示例配置
# RDB 配置
save 900 1 # 900 秒内至少 1 个写操作
save 300 10 # 300 秒内至少 10 个写操作
save 60 10000 # 60 秒内至少 10000 个写操作
# AOF 配置
appendonly yes # 启用 AOF
appendfsync everysec # 每秒同步
appendfilename "appendonly.aof"
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb提示
- RDB:快照持久化
- AOF:日志持久化
- 考虑数据安全性、性能、恢复速度
解法
参考答案 (3 个标签)
RDB AOF 持久化
RDB(Redis Database)
工作原理
# RDB 生成过程
1. Redis fork 子进程
2. 子进程遍历数据库,写入临时文件
3. 子进程完成,替换旧的 RDB 文件
4. Redis 主进程继续处理命令
# COW(Copy On Write)
# fork 后,父子进程共享内存
# 写时复制,避免数据不一致RDB 文件格式
REDIS0009 # 魔数
ver # 版本
databases # 数据库
db_number # 数据库编号
key_value_pairs # 键值对
EOF # 结束标志优缺点
优点:
- 文件紧凑,占用空间小
- 恢复速度快(直接加载)
- 对性能影响小(fork 子进程)
缺点:
- 可能丢失数据(fork 之间的修改)
- fork 时可能阻塞(数据量大)
- 不能实时持久化
AOF(Append Only File)
工作原理
# AOF 写入过程
1. 命令执行后,写入 AOF 缓冲区
2. 根据策略,缓冲区写入文件
- appendfsync always: 每次写入
- appendfsync everysec: 每秒写入
- appendfsync no: 由操作系统决定
3. AOF 文件过大时,执行 AOF 重写AOF 重写
# AOF 重写过程
1. Redis fork 子进程
2. 子进程读取当前数据,生成新 AOF 文件
3. 主进程继续写入,记录到重写缓冲区
4. 子进程完成,合并重写缓冲区
5. 替换旧的 AOF 文件
# 手动触发
BGREWRITEAOF
# 自动触发
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb优缺点
优点:
- 数据安全性高(最多丢失 1 秒)
- AOF 文件可读(文本格式)
- 可修复损坏的文件
缺点:
- 文件大,占用空间多
- 恢复速度慢(重放命令)
- 性能影响大(每秒写入)
对比分析
性能对比
| 操作 | RDB | AOF |
|---|---|---|
| 持久化 | fork 时 | 每秒/每次 |
| CPU 开销 | 中等(fork + 压缩) | 较低(追加) |
| 内存开销 | COW | 重写时 fork |
| 磁盘 IO | 较大(一次性) | 较小(增量) |
数据完整性
| 策略 | 数据丢失 | 性能 |
|---|---|---|
| RDB | 分钟级 | 高 |
| AOF always | 无丢失 | 低 |
| AOF everysec | 秒级 | 中 |
| AOF no | 依赖 OS | 高 |
恢复速度
# RDB 恢复
# 直接加载二进制文件
# 时间:秒级(100MB 数据)
# AOF 恢复
# 重放所有命令
# 时间:分钟级(100MB 数据)混合持久化
Redis 4.0+
# 启用混合持久化
aof-use-rdb-preamble yes
# 工作原理
# AOF 文件 = RDB 数据 + AOF 增量
# 1. RDB: 基础数据(快照)
# 2. AOF: 增量命令(重写后的修改)
# 优势
# - 恢复速度快(RDB 部分)
# - 数据完整(AOF 部分)选择建议
| 场景 | 推荐方案 |
|---|---|
| 数据不敏感 | RDB |
| 数据敏感 | AOF everysec |
| 性能优先 | RDB |
| 兼顾性能和安全 | 混合持久化 |
| 测试环境 | 无持久化 |
实战案例
案例 1:缓存应用
# 场景:Redis 作为缓存
# 策略:RDB
# 配置
save 900 1
save 300 10
save 60 10000
appendonly no
# 原因
# - 数据可从数据库恢复
# - RDB 恢复快,重启快案例 2:消息队列
# 场景:Redis 作为消息队列
# 策略:AOF everysec
# 配置
appendonly yes
appendfsync everysec
save ""
# 原因
# - 数据不能丢失
# - AOF 每秒同步,最多丢失 1 秒案例 3:主从复制
# 场景:主从架构
# 策略:主节点关闭持久化,从节点持久化
# 主节点
save ""
appendonly no
# 从节点
save 900 1
appendonly yes
# 原因
# - 主节点专注于处理请求
# - 从节点持久化,不影响主节点性能监控和优化
查看持久化状态
# 查看 RDB 状态
INFO persistence
# rdb_changes_since_last_save: 100
# rdb_bgsave_in_progress: 0
# rdb_last_save_time: 1640995200
# 查看 AOF 状态
INFO persistence
# aof_enabled: 1
# aof_rewrite_in_progress: 0
# aof_last_bgrewrite_time_sec: 1
# aof_current_size: 100000000优化建议
# 1. fork 优化
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
# 减少内存使用,降低 fork 开销
# 2. AOF 重写优化
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 避免频繁重写
# 3. 禁用 THP
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 降低 fork 延迟
# 4. 单机实例
# 避免多实例,降低 fork 开销