Redis 的持久化机制是其高可用性的基石,主要包含 RDB (Redis Database) 和 AOF (Append Only File) 两种方式,它们的设计目标、实现原理和适用场景各有不同。
一、RDB (Redis Database) - 快照
-
原理:
- RDB 在指定的时间间隔内,将内存中整个 Redis 数据集生成一个时间点快照 (Point-in-Time Snapshot)。
- 生成快照的过程:
- Redis 主进程
/* by 01022.hk - online tools website : 01022.hk/zh/imagetopng.html */ fork
出一个子进程。 - 子进程将内存中的数据序列化写入一个临时的 RDB 文件。
- 在子进程完成写入后,用这个新的 RDB 文件替换旧的 RDB 文件(
/* by 01022.hk - online tools website : 01022.hk/zh/imagetopng.html */ rename
操作是原子的)。
- Redis 主进程
- RDB 文件是一个二进制压缩文件,结构紧凑。
-
触发方式:
- 手动触发:
SAVE
: 阻塞 Redis 主进程,直到 RDB 文件创建完毕。生产环境几乎不用,会导致服务长时间不可用。BGSAVE
: 后台异步进行快照生成。Redis 会fork
子进程来完成工作,主进程继续提供服务。推荐使用。
- 自动触发:
- 根据配置文件
redis.conf
中的save <seconds> <changes>
规则触发BGSAVE
。例如:save 900 1
: 900秒(15分钟)内有至少1个key发生变化。save 300 10
: 300秒(5分钟)内有至少10个key发生变化。save 60 10000
: 60秒内有至少10000个key发生变化。
- 执行
SHUTDOWN
命令关闭服务器时(如果未配置 AOF 或 AOF 未开启)。 - 主从复制时,主节点收到
SYNC
命令开始全量复制时会自动触发BGSAVE
生成 RDB 发送给从节点。
- 根据配置文件
- 手动触发:
-
优点:
- 性能高,恢复速度快: RDB 文件是紧凑的二进制文件,生成和加载(启动恢复)都非常快,非常适合大规模数据恢复和灾难恢复。
- 磁盘空间占用小: 二进制压缩格式显著减小了磁盘占用。
- 最大化 Redis 性能:
BGSAVE
由子进程完成,主进程只承担fork
的短暂开销,对读写服务影响较小。 - 适合备份: 单个文件方便备份和传输到远程数据中心或云存储。
-
缺点:
- 数据丢失风险高: 两次快照之间的数据修改会丢失。如果配置为每5分钟保存一次,服务器故障可能丢失最多5分钟的数据。对数据安全性要求高的场景不合适。
fork
可能阻塞服务: 如果数据集非常大(例如几十GB),fork
操作本身可能比较耗时(尤其是在虚拟机上),导致主进程短暂停顿(毫秒到秒级),影响服务响应时间。- 版本兼容性: 老版本 Redis 生成的 RDB 文件可能无法在新版本 Redis 上恢复。
二、AOF (Append Only File) - 日志追加
-
原理:
- AOF 记录 Redis 服务器收到的每一条写命令(及其参数)。
- 这些命令以 Redis 协议格式追加写入到 AOF 文件的末尾。
- Redis 重启时,通过重新执行 AOF 文件中的所有写命令来重建内存数据集状态。
- AOF 重写: 为了解决 AOF 文件不断膨胀的问题,Redis 会定期根据内存中的当前数据状态,创建一个新的、更小的 AOF 文件来替换旧的。重写过程由子进程完成(类似
BGSAVE
),期间新的写命令会同时记录到内存缓冲区和旧的 AOF 文件中。重写完成后,缓冲区内容追加到新 AOF 文件,然后原子替换旧文件。
-
触发方式与配置:
- 开启 AOF: 在
redis.conf
中设置appendonly yes
。 - 写入策略 (appendfsync): 控制何时将 AOF 缓冲区的内容同步到磁盘,这是影响性能和数据安全性的关键配置。
no
: 由操作系统决定何时同步。性能最好,但数据丢失风险最高(操作系统缓存未写入磁盘的数据在宕机时会丢失)。always
: 每个写命令都同步到磁盘。数据最安全(最多丢失一个命令),但性能最差(磁盘 I/O 成为瓶颈)。everysec
(默认): 每秒同步一次。在性能和数据安全性之间取得良好平衡。理论上最多丢失1秒的数据。这是最常用的配置。
- AOF 重写触发:
- 手动触发:执行
BGREWRITEAOF
命令。 - 自动触发:根据
redis.conf
中的auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
配置。例如:auto-aof-rewrite-percentage 100
(当前 AOF 文件大小比上次重写后的大小增长了100%)auto-aof-rewrite-min-size 64mb
(且当前 AOF 文件大小至少达到 64MB)
- 手动触发:执行
- 开启 AOF: 在
-
优点:
- 数据安全性高: 默认的
everysec
策略最多丢失1秒数据,always
策略理论上不丢失数据(但性能极低)。非常适合对数据完整性要求高的场景。 - 可读性(一定程度上): AOF 文件是文本格式(Redis 协议),便于人工理解和修复(虽然通常不直接编辑)。
- 容灾性强: 即使文件末尾因故障写入不完整,Redis 自带工具
redis-check-aof
可以轻松修复(删除不完整的命令)。 - 后台重写:
BGREWRITEAOF
由子进程执行,不影响主进程服务。
- 数据安全性高: 默认的
-
缺点:
- 文件体积大: 相比同数据集的 RDB 文件,AOF 文件通常更大(即使经过重写)。
- 恢复速度慢: 重新执行所有命令来恢复数据,比加载 RDB 文件慢得多,尤其当 AOF 文件很大时。
- 性能略低于 RDB: 即使使用
everysec
,AOF 的写入吞吐量通常也低于 RDB(尤其是在大量写入场景下)。always
策略性能影响显著。 - 历史 Bug: AOF 重写逻辑在极端情况下(如断电)曾出现过一些边界 Bug(虽然现在已比较成熟)。
三、如何选择 RDB 和 AOF?
没有绝对的最佳答案,选择取决于你的应用对数据安全性和性能的要求:
-
追求最高性能,能容忍分钟级数据丢失:
- 仅使用 RDB。 这是最简单的配置,适合缓存、会话存储等对丢失少量数据不敏感的场景。配置好
save
规则即可。
- 仅使用 RDB。 这是最简单的配置,适合缓存、会话存储等对丢失少量数据不敏感的场景。配置好
-
追求高数据安全性,能接受一定的性能损失和较慢的恢复速度:
- 仅使用 AOF (appendfsync everysec)。 这是最常见的生产环境配置,在性能和安全性之间取得了很好的平衡。适用于需要持久化订单、交易、用户状态等关键数据的场景。强烈建议启用 AOF。
-
需要非常高的数据安全性,能容忍显著性能下降:
- 仅使用 AOF (appendfsync always)。 牺牲性能换取最高的数据安全性(理论上零丢失)。仅在极端要求数据一致性的场景使用(如金融核心交易),通常需要配合高性能 SSD 磁盘。
-
希望平衡性能和数据安全性,并需要快速恢复能力:
- 同时启用 RDB 和 AOF (推荐方式)。
- 数据安全: 依赖 AOF (
appendfsync everysec
)。 - 快速恢复: 依赖 RDB。可以定期(如每天)手动执行
BGSAVE
备份 RDB,或者在配置中保留合理的save
规则(但频率可以设低一些,如save 3600 1
每小时保存一次)。 - 重启恢复流程: Redis 重启时优先使用 AOF 文件来恢复数据(因为它通常包含更完整的数据集状态)。只有当 AOF 功能关闭时,才会使用 RDB 文件恢复。
- 数据安全: 依赖 AOF (
- Redis 4.0+ 的混合持久化:
- 在
redis.conf
中设置aof-use-rdb-preamble yes
。 - AOF 重写时,子进程将内存数据以 RDB 格式写入新的 AOF 文件的开头部分(
preamble
),然后将重写期间缓冲的增量写命令以 AOF 格式追加到文件后面。 - 优点: 结合了 RDB 的快速加载(加载开头 RDB 部分)和 AOF 的数据完整性(加载后续增量命令)。生成的混合文件通常比纯 AOF 文件小,加载速度比纯 AOF 快很多。这是目前非常推荐的生产环境配置方式。
- 在
- 同时启用 RDB 和 AOF (推荐方式)。
总结与建议
- 理解风险: 评估应用能容忍多少数据丢失(RPO - Recovery Point Objective)。
- 基准测试: 在你的硬件和工作负载下测试不同配置的性能(吞吐量、延迟)。
- 生产推荐:
- 首选方案: 同时启用 RDB 和 AOF (
appendfsync everysec
),并开启混合持久化 (aof-use-rdb-preamble yes
)。这提供了最佳的数据安全性和较好的恢复速度。 - 纯 AOF (
appendfsync everysec
) 也是一个非常稳健的选择。 - 尽量避免仅使用 RDB,除非数据完全不重要。
- 首选方案: 同时启用 RDB 和 AOF (
- 监控与运维:
- 监控磁盘空间(AOF 文件可能很大)。
- 监控
fork
耗时(info stats
中的latest_fork_usec
)。 - 定期备份 RDB/AOF 文件到异地。
- 根据数据增长情况调整 AOF 重写触发条件 (
auto-aof-rewrite-*
)。 - 预留足够的磁盘 I/O 能力给 AOF。
最终选择应基于你的具体业务需求、数据重要性、性能预算和运维能力进行权衡。在 Redis 4.0+ 环境下,开启混合持久化通常是满足大多数生产环境需求的最佳实践。