Redis 作为一款高性能的内存数据库,其读写速度远超传统磁盘数据库。然而,内存的易失性意味着一旦 Redis 进程意外宕机或服务器断电,内存中的数据将瞬间丢失。
为了解决这个问题,Redis 提供了强大的持久化机制。本文将带你彻底搞懂 Redis 的三种持久化策略:RDB、AOF 以及 混合持久化,并解析其底层的 fork 与写时复制(COW)机制。
一、 为什么需要持久化?
Redis 是内存数据库,数据存放在内存中。持久化的核心目的,就是将内存中的数据保存到磁盘上,以便在 Redis 重启时能够恢复数据。
Redis 提供了三种持久化方式,它们各有优劣,适用于不同的业务场景。
二、 RDB (Redis DataBase) —— 内存快照
RDB 是在指定的时间间隔内,将当前内存中的全量数据生成一个快照(Snapshot),保存为一个压缩的二进制文件(.rdb)。
· 手动触发:
· save:阻塞主线程进行快照,不推荐(会导致服务短暂不可用)。
· bgsave:默认方式。主进程 fork 出一个子进程,由子进程去执行快照,主进程继续处理客户端请求。
· 自动触发:在 redis.conf 中配置 save 。例如 save 900 1 表示 900 秒内至少有 1 个 key 被修改,就自动触发 bgsave。
· 优点:文件体积小,适合做冷备(备份到远程服务器);恢复速度极快。
· 缺点:数据安全性低。因为是周期性保存,如果 Redis 意外宕机,会丢失最后一次快照之后的所有数据(可能丢几分钟的数据)。
三、 AOF (Append Only File) —— 追加日志
AOF 类似于 MySQL 的 binlog。Redis 会将所有执行的写命令(如 set、del)以追加的方式写入一个日志文件(.aof)。重启时,通过重放这些命令来恢复数据。
· always:每个写命令都立刻同步到磁盘。最安全,但性能最差。
· everysec:每秒同步一次。默认配置,兼顾性能和安全(最多丢 1 秒数据)。
· no:由操作系统决定何时同步。性能最好,但安全性最差。
因为 AOF 记录的是命令,文件会越来越大。Redis 会 fork 一个子进程,根据当前内存的数据状态,生成一个最精简的命令集(比如之前对同一个 key 做了 100 次 set,重写后只保留最后一次),替换旧文件。
· 优点:数据安全性高(默认最多丢 1 秒);可读性强。
· 缺点:文件体积通常比 RDB 大;恢复速度慢(需要一条条重放命令)。
四、 混合持久化 (Redis 4.0 引入)
结合了 RDB 和 AOF 的优点。在 AOF 重写时,不再直接写命令,而是将当前内存的数据以 RDB 格式写入 AOF 文件的开头,后续的增量写命令继续以 AOF 格式追加。
· 重启恢复时,先加载 RDB 部分(极快),再重放增量 AOF 命令(数据全)。
· 兼具了 RDB 的恢复速度 和 AOF 的数据低丢失率。
· 配置:在 redis.conf 中设置 aof-use-rdb-preamble yes(Redis 4.0 后默认开启)。
五、 深入底层:fork 与写时复制(COW)
无论是 RDB 还是 AOF 重写,都会涉及到 fork 子进程。这里有一个极易产生的认知误区。
常见误区:“子进程去执行啥呀?把二进制文件转换成数据吗?”
真相是:恰恰相反。
阶段一:保存(bgsave 时,子进程在干嘛?)
为什么非要子进程来做? 因为 Redis 处理客户端命令是单线程的。如果主进程自己去遍历内存并写磁盘,由于磁盘 I/O 极慢,主进程会被长时间阻塞,所有客户端请求都会卡死。
这里利用了操作系统的 写时复制(Copy-On-Write, COW) 机制:fork 瞬间并不复制物理内存,只有当主进程处理写命令修改数据时,才会复制被修改的那部分内存页。这保证了子进程看到的数据是 fork 那一刻的“冻结”快照。
阶段二:恢复(Redis 重启时,谁在干嘛?)
当你重启 Redis 时,没有子进程,是主进程亲自干活。主进程读取磁盘上的 .rdb 文件,把读到的二进制数据反序列化,在内存中重建数据结构。
总结:子进程是在保存阶段,帮主进程把内存数据“拍快照”并写入磁盘;而在重启加载阶段,是主进程自己把磁盘二进制“解压”回内存。
六、 生产环境最佳实践与面试必问
听 AOF 的。 因为 AOF 的数据通常比 RDB 更完整。如果 AOF 关闭或者文件损坏,才会去加载 RDB。
· 纯缓存场景:可以关闭所有持久化,追求极致性能。
· 数据不能丢,但能容忍分钟级丢失:只开 RDB(比如 save 60 1000)。
· 数据绝对不能丢(或只能容忍秒级丢失):同时开启 RDB 和 AOF。
· 用 RDB 做定期的冷备(比如每天凌晨备份一次到 S3/OSS)。
· 用 AOF (everysec) 保证 Redis 意外宕机时,只丢 1 秒数据。
· 开启混合持久化 (aof-use-rdb-preamble yes) 加快重启恢复速度。
· 阻塞:fork 本身会短暂阻塞主线程,但时间极短(微秒级),取决于内存页表大小。
· 内存翻倍:fork 后,子进程和主进程共享内存。只有当主进程修改某块数据时,才会复制一份该数据的物理内存给子进程(写时复制)。所以内存不会立刻翻倍,但极端情况下(所有数据都被修改)可能会接近翻倍。
结语
Redis 的持久化机制是保证数据高可靠性的基石。理解 RDB、AOF 和混合持久化的底层原理,不仅能帮助你在面试中对答如流,更能让你在实际生产环境中,根据业务对性能和数据安全性的要求,做出最合理的配置选择。




