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 的增量安全性,是目前企业部署中较为主流的方案。
恢复时间与数据安全的权衡
恢复时间主要由文件大小和装载方式决定。RDB 是二进制格式,装载时直接反序列化,速度最快;纯 AOF 需要逐条重放命令,数据集越大恢复越慢;混合持久化则先快速装载 RDB 前导,再回放少量增量,恢复时间接近 RDB 而数据安全性接近 AOF。数据安全方面,RDB 的丢失窗口取决于 save 规则,可能是几分钟甚至更久;AOF everysec 的丢失窗口约为 1 秒;always 几乎不丢,但性能代价高。
企业部署中常见的组合是:开启 AOF 并设置 appendfsync everysec,同时开启混合持久化,保留 RDB 用于定期冷备。这样既保证了在线服务的数据安全,又能在故障恢复时快速拉起。如果业务允许分钟级数据丢失且追求极致性能,可以只保留 RDB;如果对数据零丢失有硬性要求,则需要评估 always 带来的吞吐下降是否可接受。
BGSAVE 或等待 AOF 刷盘,然后重启实例,检查最后一条数据的序号,即可量化实际的丢失窗口和恢复耗时。
rdb_last_bgsave_status、aof_last_bgrewrite_status 等指标,并定期备份持久化文件到独立存储。
总结来说,RDB 与 AOF 不是互斥选择,而是可以叠加的安全层。理解 fork 与写时复制的内存代价、fsync 策略的性能含义、以及混合持久化的恢复路径,才能根据业务对恢复时间(RTO)和数据丢失容忍度(RPO)的要求,做出合理的持久化选型。