3. Redis持久化机制与选型

Redis 是内存数据库,一旦进程退出或主机断电,内存中的数据就会消失。持久化机制要解决的核心问题只有一个:把内存中的数据集以某种形式落到磁盘,并在重启时重新装载。Redis 提供了两条技术路线——RDB 快照与 AOF 日志,以及把两者结合的混合持久化。理解它们的原理差异,才能在企业缓存平台中做出正确的选型。

RDB:某一时刻的全量快照

RDB(Redis Database)在指定时间点把整个数据集序列化成一个紧凑的二进制文件,默认名为 dump.rdb。触发方式有两类:一是配置规则自动触发,例如 save 900 1 表示 900 秒内至少有 1 次写操作就生成快照;二是手动执行 BGSAVE。执行 BGSAVE 时,Redis 主进程会 fork 出一个子进程,由子进程完成文件写入,主进程继续处理客户端请求,因此对在线服务的影响相对可控。

这里的关键机制是写时复制(Copy-On-Write)。fork 之后父子进程共享同一份物理内存页,只有当主进程修改某个键时,操作系统才会为该页复制一份副本。这意味着快照期间如果写入量很大,内存占用会明显上升,极端情况下可能触发 OOM。因此 RDB 的选型要点是:恢复速度快、文件体积小、适合做冷备和全量迁移,但两次快照之间的数据会丢失,无法做到秒级数据安全。

AOF:追加写命令日志

AOF(Append Only File)记录的是每一条会改变数据集的写命令,以 Redis 协议格式追加到文件末尾。重启时,Redis 重新执行这些命令来重建数据。AOF 默认关闭,需要设置 appendonly yes 开启。由于命令是持续追加的,AOF 的数据安全性天然高于 RDB,但文件会不断膨胀,因此 Redis 提供了 AOF 重写(BGREWRITEAOF):子进程根据当前数据集生成一份最小命令集,替换旧文件,从而压缩体积。

AOF 的核心参数是 appendfsync,它决定内核缓冲区中的数据何时真正刷到磁盘,直接决定数据安全与性能的平衡:

fsync 策略行为数据安全性能影响
always每条写命令都 fsync最高,最多丢 1 条命令最大,QPS 显著下降
everysec每秒 fsync 一次(默认)最多丢约 1 秒数据较小,推荐生产使用
no由操作系统决定刷盘时机最低,可能丢数十秒最小

生产环境通常选择 everysec:它在数据安全和吞吐之间取得了较好的折中。如果业务对数据丢失极度敏感(如金融交易流水),才考虑 always,但必须接受性能代价。

混合持久化:兼顾恢复速度与数据安全

Redis 4.0 引入了混合持久化(aof-use-rdb-preamble yes)。开启后,AOF 重写生成的文件由两部分组成:前半部分是当前数据集的 RDB 格式快照,后半部分是重写期间新产生的增量写命令。重启时,Redis 先加载 RDB 部分快速恢复大部分数据,再回放增量命令补齐最新状态。这样既避免了纯 AOF 恢复时逐条重放命令的缓慢,又保留了 AOF 的增量安全性,是目前企业部署中较为主流的方案。

Redis 持久化机制与恢复路径 内存数据集 键值对 + 过期时间 写命令持续到达 RDB 快照 BGSAVE / fork 子进程 全量二进制,体积小 AOF 日志 追加写命令 appendfsync 控制刷盘 混合持久化 RDB 前导 + AOF 增量 aof-use-rdb-preamble yes 恢复快 + 数据安全 磁盘文件 dump.rdb / appendonly.aof 重启恢复 加载快照 + 回放增量 选型权衡 RDB:恢复快、文件小,但两次快照间数据可能丢失 → 适合冷备、全量迁移 AOF everysec:最多丢约 1 秒数据,性能损耗小 → 适合对数据安全有要求的生产缓存

恢复时间与数据安全的权衡

恢复时间主要由文件大小和装载方式决定。RDB 是二进制格式,装载时直接反序列化,速度最快;纯 AOF 需要逐条重放命令,数据集越大恢复越慢;混合持久化则先快速装载 RDB 前导,再回放少量增量,恢复时间接近 RDB 而数据安全性接近 AOF。数据安全方面,RDB 的丢失窗口取决于 save 规则,可能是几分钟甚至更久;AOF everysec 的丢失窗口约为 1 秒;always 几乎不丢,但性能代价高。

企业部署中常见的组合是:开启 AOF 并设置 appendfsync everysec,同时开启混合持久化,保留 RDB 用于定期冷备。这样既保证了在线服务的数据安全,又能在故障恢复时快速拉起。如果业务允许分钟级数据丢失且追求极致性能,可以只保留 RDB;如果对数据零丢失有硬性要求,则需要评估 always 带来的吞吐下降是否可接受。

建议在部署后做一次恢复演练:写入一批带序号的数据,触发一次 BGSAVE 或等待 AOF 刷盘,然后重启实例,检查最后一条数据的序号,即可量化实际的丢失窗口和恢复耗时。
不要同时依赖 RDB 和 AOF 却从不验证文件完整性。磁盘写满、fork 失败、AOF 文件损坏都会导致重启时加载失败。生产环境应监控 rdb_last_bgsave_status、aof_last_bgrewrite_status 等指标,并定期备份持久化文件到独立存储。

总结来说,RDB 与 AOF 不是互斥选择,而是可以叠加的安全层。理解 fork 与写时复制的内存代价、fsync 策略的性能含义、以及混合持久化的恢复路径,才能根据业务对恢复时间(RTO)和数据丢失容忍度(RPO)的要求,做出合理的持久化选型。