Redis 持久化机制:RDB、AOF 与混合持久化深度解析
前言
Redis 的持久化机制是保障数据安全的核心。理解 RDB 快照和 AOF 日志的工作原理,是正确配置 Redis 可靠性的前提。本文深入讲解两种持久化方案、混合持久化以及生产环境的配置策略。
为什么需要持久化
Redis 的数据存储在内存中,断电、进程崩溃或重启都会导致数据丢失。对于需要数据可靠性的业务(如排行榜、购物车、用户 Session),必须配置持久化机制。即使作为纯缓存使用,持久化也能在故障恢复时预热缓存,减少对后端数据库的压力。
RDB 快照:全量备份
RDB 是 Redis 的全量快照机制,通过 BGSAVE 或 SAVE 命令,在指定时刻 fork 一个子进程,将内存数据序列化写入二进制文件(dump.rdb)。
工作流程:
1. 父进程 fork 一个子进程(Copy-On-Write,父进程继续处理请求)
2. 子进程遍历内存数据,将数据序列化写入临时文件
3. 写入完成后,用临时文件原子替换旧的 RDB 文件
# 手动触发 RDB 快照
redis-cli BGSAVE -- 后台异步执行,不阻塞主进程
redis-cli SAVE -- 同步执行,阻塞主进程
# 查看后台保存状态
redis-cli INFO persistence
-- rdb_bgsave_in_progress: 0 或 1
-- rdb_last_save_time: 上次保存的时间戳
-- rdb_last_bgsave_status: ok 或 err
# redis.conf RDB 配置
save 900 1 -- 900 秒内至少有 1 次修改则触发 BGSAVE
save 300 10 -- 300 秒内至少有 10 次修改则触发 BGSAVE
save 60 10000 -- 60 秒内至少有 10000 次修改则触发 BGSAVE
dbfilename dump.rdb
dir /var/lib/redis
stop-writes-on-bgsave-error yes -- BGSAVE 失败时停止写入
rdbcompression yes -- 压缩 RDB 文件
rdbchecksum yes -- RDB 文件末尾添加校验和
RDB 的优点:
- 全量备份,文件紧凑,适合备份、灾难恢复
- fork 子进程执行,不阻塞主进程
- 恢复大数据集时比 AOF 快
RDB 的缺点:
- 无法做到实时持久化(最多 save 间隔内的数据丢失)
- fork 子进程时,如果数据量大会消耗额外内存(Copy-On-Write)
- 不同 Redis 版本之间的 RDB 文件可能不兼容
AOF 日志:增量追加
AOF(Append Only File)通过记录每次写命令来实现持久化。每次执行写操作后,命令以 Redis 协议格式追加到文件末尾。数据丢失最多只丢失 1 秒的数据(取决于刷盘策略)。
AOF 工作模式:
- <strong>always</strong>:每个写命令都同步写入磁盘,最安全但最慢
- <strong>everysec</strong>:每秒同步一次(默认),折中方案,最多丢失 1 秒数据
- <strong>no</strong>:由操作系统决定何时同步,最快但最不可靠
# redis.conf AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# AOF 重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# RDB 和 AOF 混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes
# 查看 AOF 状态
redis-cli INFO persistence
# 手动触发 AOF 重写
redis-cli BGREWRITEAOF
AOF 的优点:
- 数据安全性更高(everysec 模式最多丢失 1 秒数据)
- append-only 模式,只追加写磁盘
- AOF 文件可读,便于人工干预和数据修复
AOF 的缺点:
- 文件体积通常比 RDB 大
- 需要通过 AOF 重写压缩文件
- 恢复速度比 RDB 慢
混合持久化:最优方案
Redis 4.0 引入了混合持久化,结合 RDB 和 AOF 的优点。重写 AOF 时,先以 RDB 格式写入全量数据,然后继续以 AOF 格式追加增量修改。
# 开启混合持久化
aof-use-rdb-preamble yes
# 查看混合持久化的 AOF 文件结构
# 前半部分是 RDB 格式(二进制),后半部分是 AOF 格式(文本)
# 52 45 44 49 53 开头是 RDB 魔术数 "REDIS"
混合持久化的优势:
- 恢复时先加载 RDB 部分(快速恢复全量数据)
- 再重放 AOF 部分(恢复增量修改)
- AOF 文件体积比纯 AOF 小
数据恢复流程
# 1. 如果开启了 AOF,优先使用 AOF 恢复
# 2. 如果 AOF 关闭或 AOF 文件不存在,使用 RDB 恢复
# 3. 如果两者都没有,Redis 启动为空数据集
# 备份当前数据文件
cp /var/lib/redis/appendonly.aof /backup/appendonly.aof.$(date +%Y%m%d%H%M%S)
cp /var/lib/redis/dump.rdb /backup/dump.rdb.$(date +%Y%m%d%H%M%S)
# 使用 redis-check-aof 修复损坏的 AOF 文件
# redis-check-aof --fix /var/lib/redis/appendonly.aof
# 使用 redis-check-rdb 检查 RDB 文件
# redis-check-rdb /var/lib/redis/dump.rdb
生产环境配置建议
# 推荐的生产环境配置(混合持久化)
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
min-replicas-to-write 1 -- 至少 1 个从节点确认写入
min-replicas-max-lag 10 -- 从节点延迟超过 10 秒时拒绝写入
主从架构下的持久化策略
# 主节点:同时开启 RDB 和 AOF(数据可靠性优先)
# 从节点:可以只开启 RDB(作为备用副本)
# 主节点故障时的恢复流程
# 1. 检查主节点的 RDB/AOF 文件完整性
# 2. 如果从节点数据较新,优先从从节点恢复数据
redis-cli -h <slave_ip> SLAVEOF NO ONE
常见问题
Q1:RDB 和 AOF 可以同时关闭吗?
可以,但数据将完全不持久化,Redis 重启后数据丢失。这仅适用于纯内存缓存场景,但即便如此,关闭持久化也意味着无法通过 Redis 重启来恢复缓存预热。
Q2:AOF 重写会阻塞 Redis 吗?
AOF 重写由后台子进程执行,不会阻塞主进程。但 fork 子进程时,如果 Redis 内存使用量很大,fork 操作可能耗时较长并导致短暂卡顿。使用 Linux 透明大页(THP)会加剧这个问题,建议关闭。
Q3:混合持久化下,AOF 文件损坏如何修复?
Redis 启动时会检测 AOF 文件格式。如果 RDB 前缀部分完好,可以手动删除损坏的 AOF 文本部分,Redis 依然可以正常加载 RDB 数据。也可以使用 redis-check-aof --fix 工具修复。
延伸阅读
- Redis 数据类型完全指南
- Redis 缓存策略与实战
- Redis 官方文档:Persistence https://redis.io/docs/management/persistence/