前言
Redis 作为内存数据库,数据存储在 RAM 中,一旦服务器重启数据就会丢失。为了解决这个问题,Redis 提供了两种持久化机制:RDB(快照)和 AOF(追加日志)。本文将深入对比这两种机制的原理、配置和选择策略。
一、RDB(Redis Database)
1.1 工作原理
RDB 是将 Redis 内存中的数据以二进制快照的形式写入磁盘。触发方式有三种:
┌─────────────────────────────────────┐
│ Redis 内存数据 │
│ │
│ ┌───────┐ ┌───────┐ │
│ │ Key1 │ │ Key2 │ ... │
│ └───────┘ └───────┘ │
│ │
│ ▼ fork() 子进程 │
│ │
│ ┌─────────────────────┐ │
│ │ BGSAVE 子进程 │ │
│ │ 写入 dump.rdb │ │
│ └─────────────────────┘ │
└─────────────────────────────────────┘1.2 触发方式
手动触发:
# 阻塞式(生产环境禁用)
SAVE
# 后台异步执行(推荐)
BGSAVE自动触发(配置文件):
# redis.conf
# 900秒内至少1个key变化 → 触发RDB
save 900 1
# 300秒内至少10个key变化 → 触发RDB
save 300 10
# 60秒内至少10000个key变化 → 触发RDB
save 60 10000
# 禁用自动RDB
# save ""其他触发场景:
- 主从复制时,主节点自动触发 BGSAVE
- 执行
SHUTDOWN命令时 - 执行
FLUSHALL命令时(生成空快照)
1.3 RDB 文件配置
# redis.conf
# RDB 文件名
dbfilename dump.rdb
# 存储目录
dir /var/lib/redis
# 压缩(默认开启,用 LZF 压缩)
rdbcompression yes
# 校验和(默认开启)
rdbchecksum yes
# BGSAVE 出错时停止写入(默认yes,推荐开启)
stop-writes-on-bgsave-error yes1.4 RDB 优缺点
优点:
- 文件紧凑,体积小,适合备份和传输
- 恢复速度快(直接加载二进制数据)
- 对性能影响小(子进程异步执行)
- 适合做冷备和灾难恢复
缺点:
- 宕机时会丢失最后一次快照后的所有数据
- fork 子进程时,如果数据量大,可能造成短暂阻塞
- 不适合对数据完整性要求高的场景
二、AOF(Append Only File)
2.1 工作原理
AOF 以追加的方式将每条写命令记录到日志文件中,重启时按顺序回放命令恢复数据。
┌─────────────────────────────────────┐
│ Redis 内存数据 │
│ │
│ 客户端写入命令 │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Redis执行 │ → │ 追加到AOF缓冲 │ │
│ │ 命令 │ │ 区 │ │
│ └──────────┘ └──────┬───────┘ │
│ │ │
│ ▼ fsync │
│ ┌──────┴───────┐ │
│ │ appendonly.aof│ │
│ └──────────────┘ │
└─────────────────────────────────────┘2.2 开启 AOF
# redis.conf
appendonly yes
appendfilename "appendonly.aof"2.3 刷盘策略
# 三种 fsync 策略
# always: 每条命令都fsync(最安全,性能最差)
# everysec: 每秒fsync一次(推荐,最多丢1秒数据)
# no: 由OS决定何时fsync(性能最好,可能丢较多数据)
appendfsync everysec| 策略 | 数据安全性 | 性能 | 适用场景 |
|---|---|---|---|
| always | 最高(不丢数据) | 最差 | 对数据极其敏感 |
| everysec | 高(最多丢1秒) | 好 | 推荐默认 |
| no | 低 | 最好 | 纯缓存场景 |
2.4 AOF 重写
随着时间推移,AOF 文件会越来越大。Redis 通过"重写"机制压缩文件:分析当前内存数据,用最少的命令重新生成 AOF 文件。
# 手动触发重写
BGREWRITEAOF# redis.conf
# AOF 文件大小比上次重写后增长 100% 时自动重写
auto-aof-rewrite-percentage 100
# AOF 文件最小重写体积(64MB)
auto-aof-rewrite-min-size 64mb
# 重写期间不执行 fsync(减少磁盘 IO)
no-appendfsync-on-rewrite yes重写过程:
原始 AOF:
SET key1 "v1"
SET key1 "v2" ← 覆盖
DEL key1 ← 删除
SET key1 "v3" ← 最终值
重写后:
SET key1 "v3" ← 只保留最终状态2.5 AOF 优缺点
优点:
- 数据安全性高(最多丢 1 秒数据)
- 日志格式可读,可手动修复
- 支持实时持久化,适合对数据完整性要求高的场景
缺点:
- 文件体积比 RDB 大
- 恢复速度比 RDB 慢(需要回放命令)
- 重写时会 fork 子进程,大数据量时可能阻塞
三、RDB + AOF 混合持久化
Redis 4.0 引入混合持久化,结合两者的优点:
# redis.conf
aof-use-rdb-preamble yes工作原理:
- AOF 重写时,先以 RDB 格式写入当前内存快照
- 重写期间的增量写命令以 AOF 格式追加在 RDB 数据之后
┌────────────────────────────────────┐
│ 混合 AOF 文件 │
│ │
│ ┌──────────────────────────────┐ │
│ │ RDB 二进制数据(全量快照) │ │
│ │ - 恢复速度快 │ │
│ │ - 文件体积小 │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ AOF 增量命令(重写期间) │ │
│ │ - 保证数据不丢 │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘恢复流程:
- 先加载 RDB 部分(快速恢复大部分数据)
- 再回放 AOF 增量命令(补全重写期间的数据)
四、完整配置示例
# redis.conf 生产环境推荐配置
# ===== RDB 配置 =====
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
# ===== AOF 配置 =====
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes
# AOF 重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
no-appendfsync-on-rewrite yes五、持久化方案选择
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 纯缓存,可接受数据丢失 | 仅 RDB | 性能最优,恢复快 |
| 数据库,不可丢数据 | 仅 AOF | 数据安全性高 |
| 综合场景(推荐) | 混合持久化 | 兼顾性能和安全 |
| 灾备备份 | RDB + 定时备份 | 文件小,传输快 |
备份策略建议
#!/bin/bash
# 每日凌晨2点备份 RDB 文件
BACKUP_DIR="/backup/redis/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 触发 BGSAVE
redis-cli BGSAVE
# 等待完成
while [ $(redis-cli INFO persistence | grep rdb_bgsave_in_progress | tr -d '\r') != "0" ]; do
sleep 1
done
# 复制文件
cp /var/lib/redis/dump.rdb $BACKUP_DIR/
# 保留最近7天
find /backup/redis/ -type d -mtime +7 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_DIR/dump.rdb"六、故障恢复
AOF 文件损坏修复
# 如果 AOF 文件损坏,Redis 无法启动
redis-check-aof --fix appendonly.aof
# 检查 RDB 文件
redis-check-rdb dump.rdb从备份恢复
# 1. 停止 Redis
systemctl stop redis
# 2. 替换 RDB 文件
cp /backup/redis/20260724/dump.rdb /var/lib/redis/
# 3. 如果不想用 AOF,临时关闭
# 修改 redis.conf: appendonly no
# 4. 启动 Redis
systemctl start redis
# 5. 验证数据
redis-cli DBSIZE总结
| 对比项 | RDB | AOF | 混合持久化 |
|---|---|---|---|
| 数据安全 | 可能丢分钟级数据 | 最多丢1秒 | 最多丢1秒 |
| 文件大小 | 小 | 大 | 中 |
| 恢复速度 | 快 | 慢 | 快 |
| 性能影响 | 小(fork时短暂) | 中(每秒fsync) | 中 |
| 推荐场景 | 备份/缓存 | 数据库 | 生产推荐 |
生产环境推荐开启混合持久化,同时定期备份 RDB 文件做异地灾备。
评论 (0)