# 30. Redis 如何实现数据的持久化并确保在故障后数据不丢失?
# 标准答案
Redis 通过 RDB(Redis Database) 和 AOF(Append-Only File) 两种方式实现持久化,分别对应 快照存储 和 日志存储:
- RDB(快照持久化):周期性将 Redis 内存数据写入二进制文件
dump.rdb
,适用于高效备份,但可能丢失最近修改的数据。 - AOF(日志持久化):以追加方式记录每次写操作,适用于高可靠性,故障恢复时可以重放日志确保数据一致。
确保数据不丢失的策略:
- 开启 AOF,并使用
fsync=always
(每次写入立即刷盘),但会影响性能。 - 结合 AOF + RDB(混合持久化),兼顾性能和数据安全。
- 配置主从复制 + 哨兵,在节点故障时快速恢复。
# 答案解析
# 1️⃣ Redis 的两种持久化方案
Redis 默认是基于内存存储的,但为了防止宕机后数据丢失,提供 RDB 和 AOF 两种持久化机制。
持久化方式 | 存储方式 | 恢复速度 | 数据丢失风险 | 适用场景 |
---|---|---|---|---|
RDB(快照) | 定期保存快照 dump.rdb | 快 | 可能丢失最近数据 | 备份、快速重启 |
AOF(日志) | 记录写操作 appendonly.aof | 慢 | 可靠(可配置刷盘策略) | 高数据安全要求 |
# 2️⃣ RDB(快照持久化)
# 🔹(1)RDB 工作原理
Redis 会 周期性地将内存中的数据保存为 dump.rdb
文件,以便在 Redis 进程重启后恢复数据。
- 触发方式:
- 手动触发:执行
SAVE
或BGSAVE
命令。 - 自动触发:配置
save
规则,例如save 60 1000
(60 秒内有 1000 次修改则触发)。
- 手动触发:执行
📌 RDB 生成快照的两种方式:
方式 | 说明 | 是否阻塞 |
---|---|---|
SAVE | 主线程直接写入 RDB | 阻塞 |
BGSAVE | fork 子进程写入 RDB | 非阻塞 |
# RDB 持久化配置示例
save 900 1 # 900秒内有1次写操作则触发 RDB
save 300 10 # 300秒内有10次写操作
save 60 10000 # 60秒内有10000次写操作
1
2
3
4
2
3
4
# 🔹(2)RDB 的优缺点
✅ 优点:
- 文件体积小,恢复快(二进制压缩存储)。
- 对读写性能影响小(子进程处理)。
- 适用于定期备份,减少数据丢失风险。
❌ 缺点:
- 数据可能丢失(快照是定期生成的,崩溃后可能丢失最近修改的数据)。
- fork 过程开销较大(创建子进程会占用 CPU 和内存)。
# 3️⃣ AOF(日志持久化)
# 🔹(1)AOF 工作原理
AOF 以 追加(Append-Only) 方式将 所有写命令 记录到 appendonly.aof
文件,并在 Redis 启动时 重放日志 恢复数据。
📌 AOF 写入策略(appendfsync
配置项):
配置 | 刷盘方式 | 性能 | 数据安全 |
---|---|---|---|
always | 每次写入都 fsync | 最慢 | 最安全 |
everysec | 每秒 fsync 一次(默认) | 较快 | 可能丢失 1 秒数据 |
no | 由操作系统控制 fsync | 最快 | 可能丢失更多数据 |
# AOF 持久化配置
appendonly yes # 开启 AOF
appendfsync everysec # 每秒写入磁盘
1
2
3
2
3
# 🔹(2)AOF 日志重写
AOF 日志文件会 随着操作增多变得很大,Redis 提供 AOF 重写机制:
- 合并重复命令(
SET a 1, SET a 2
->SET a 2
)。 - 减少日志体积(提高恢复速度)。
触发方式:
- 自动触发(配置
auto-aof-rewrite-percentage
)。 - 手动触发:执行
BGREWRITEAOF
命令。
# 🔹(3)AOF 的优缺点
✅ 优点:
- 可靠性高,基本不丢数据(
fsync=always
)。 - 可读性好(AOF 以命令格式存储)。
- 日志可修复(手动修改 AOF 文件)。
❌ 缺点:
- 比 RDB 慢(日志记录方式导致开销较大)。
- AOF 文件比 RDB 大(存储更多数据)。
- 恢复速度较慢(需要重放所有写命令)。
# 4️⃣ RDB vs. AOF,如何选择?
对比项 | RDB | AOF |
---|---|---|
触发方式 | 定期快照 | 实时追加 |
恢复速度 | 快 | 慢(重放日志) |
数据丢失风险 | 可能丢失最近修改的数据 | 几乎不丢数据(取决于 appendfsync 配置) |
文件大小 | 小 | 大 |
适用场景 | 快速备份、冷启动 | 高可靠性场景 |
最佳方案:
- 如果希望高可靠性 → 开启 AOF(
appendfsync everysec
)。 - 如果希望快速恢复 → 使用 RDB(
save 60 10000
)。 - 推荐:RDB + AOF 混合持久化,兼顾 性能与可靠性。
# Redis 6.0 支持 AOF + RDB 混合持久化
aof-use-rdb-preamble yes
1
2
2
在 AOF 之前先保存 RDB 快照,提升恢复速度。
# 5️⃣ 数据一致性与可靠性方案
Redis 单机模式下,仅靠持久化 不能保证 100% 数据可靠,需要 主从复制 + 哨兵 + 持久化 结合使用:
- RDB + AOF → 解决单机持久化问题。
- 主从复制 → 保障高可用,避免单点故障。
- Redis Sentinel(哨兵) → 自动监控并切换主节点。
- Redis Cluster → 采用哈希槽分片,提高扩展性。
# 深入追问
🔹 为什么 Redis 6.0 之后推荐使用 RDB + AOF 混合模式?
🔹 AOF 重写过程中 Redis 是否可以正常工作?为什么?
🔹 Redis 发生宕机时,RDB 和 AOF 各自能恢复多少数据?
# 相关面试题
🔹 Redis RDB 触发 BGSAVE
时,如果 fork 失败会发生什么?
🔹 Redis 为什么不使用 WAL(Write-Ahead Logging)方式?
🔹 Redis 如何保证 AOF 日志在磁盘损坏后仍可恢复?
# 总结
- RDB 适用于 定期备份,恢复快但可能丢数据。
- AOF 适用于 高可靠性,写入日志但恢复慢。
- 最佳方案:RDB + AOF 混合模式,在性能和数据安全之间取得平衡。
- 结合主从复制 + 哨兵/集群,确保 Redis 高可用和数据一致性。