〇、前言
Redis 持久化主要有两种:RDB(数据快照模式)、AOF(追加模式),另外就是这两种模式的混合模式用。
本文将对这三种情况进行详细介绍。
博主 Redis 相关文章都在这里了:https://www.cnblogs.com/hnzhengfy/category/2229717.html
一、RDB(数据快照模式)
1.1 简介
RDB(Redis Database Snapshot 快照)是 Redis 数据持久化的一种方式,又称为 Snapshot,默认情况下 Redis 在指定的时间间隔内将内存中的数据集快照写入磁盘,存放在副本文件中。当 Redis 重启后又自动读取到内存中。
- 工作原理
**创建子进程:**在执行 RDB 快照时,Redis 会调用 fork 函数创建一个子进程,尽管Redis本身是单线程运行的。这个子进程与父进程共享内存空间,但拥有独立的地址空间。
**写入数据:**子进程遍历数据库中的每个键值对,并将其序列化后写入到一个新的 RDB 文件中。在这个过程中,主进程仍然可以处理客户端的请求,不会受到磁盘写入操作的影响。
**替换原有文件:**当子进程完成写入操作后,它会用新生成的 RDB 文件替换掉原有的 RDB 文件,从而完成一次完整的快照过程。
关于 fork(),它是 Unix 和类 Unix 操作系统(如 Linux)中的一个关键系统调用,用于创建一个新的进程,这个新进程是原进程的副本,称为子进程。原进程则被称为父进程。fork() 的主要作用是在程序中实现并行处理和任务分解。
- 为什么需要使用 fork 函数来创建子进程?
避免阻塞主线程: Redis 的主要任务是处理客户端请求。**如果直接在主线程中生成 RDB 文件,那么在生成过程中,主线程将无法处理其他客户端请求,这会导致服务暂时不可用。**通过 fork() 创建一个子进程来执行这个耗时的操作,可以确保主线程继续响应客户端请求。
保证数据一致性:fork() 创建的子进程会继承父进程的数据段(包括内存中的键值对)。这意味着,在子进程开始生成 RDB 文件的那一刻,它所看到的数据是一个完整的、一致的快照。这样即使在生成 RDB 文件的过程中有新的写操作发生,也不会影响到正在生成的 RDB 文件内容。
fork() 生成的子进程拥有与父进程相同的内存映像,但是它是只读的。也就是说,子进程和父进程共享同一块物理内存,直到其中一方尝试修改这块内存的内容(这被称为"写时复制",Copy-On-Write) 。即当父进程或子进程试图修改某一块内存时,操作系统会为该块内存分配一个新的副本,只有在这个时候才会实际复制数据。因此,在生成RDB文件的过程中,除非有大量写操作发生,否则父子进程之间实际上不需要进行大量的内存复制,从而提高了效率。
如下示意图:

- RDB 模式的优势
高性能: 由于使用了 fork() 创建的子进程,主进程不会被磁盘写入操作阻塞,从而保持了 Redis 的高性能。
适合大规模数据恢复: RDB 文件是一个紧凑的二进制文件,包含了当前数据库中所有的键值对数据和对应的过期时间。当需要恢复数据时,Redis 可以直接从 RDB 文件加载数据,而不需要重新执行所有的写操作,从而实现快速恢复。
**空间效率高:**相对于 AOF(Append-Only File)持久化来说,RDB 文件占用更少的磁盘空间,易于传输和存储。
- RDB 模式的劣势
数据丢失风险: 持久化的数据可能会出现丢失的情况。因为在持久化进行过程中,或者在未到触发备份的节点但已有数据发生变更 ,这时服务器突然宕机,存储的数据可能并不完整。
Fork 耗时问题: 如果数据集很大 ,Fork 可能会很耗时,并且如果 CPU 性能不好的话,可能会导致 Redis 在几毫秒甚至一秒钟内停止为客户端提供服务。
配置项复杂性增加: 需要仔细配置触发快照的条件(例如,在多少秒内有多少键发生变化),以平衡性能和数据安全的需求。错误的配置可能导致过多或过少的快照生成,影响系统性能或数据安全性。
1.2 触发方式一:自动触发
- 配置触发
在Redis的配置文件中,可以通过设置save m n参数来指定在多长时间内数据集存在多少次修改时自动触发RDB快照。
例如,save 900 1
表示在 900 秒内至少有 1 个键被修改时触发 RDB 快照。
其他相关的配置项:
stop-writes-on-bgsave-error:默认情况下,如果 RDB 快照过程中出现错误,Redis 会继续接受写操作。可以通过设置该选项为 yes,让 Redis 在 RDB 快照出错时停止写操作,以避免数据丢失 。
rdbchecksum:默认开启,表示在存储快照后,Redis 使用 CRC64 算法来进行数据校验。这个操作会增加一定的性能消耗,如果希望获取最大的性能提升,可以关闭此功能。
rdbcompression:用于配置是否对磁盘中的快照文件进行压缩存储。 如果是的话,Redis 会采用 LZF 算法进行压缩,可以减少磁盘空间的占用,但会消耗一定的 CPU 性能。如果不希望消耗 CPU 性能来进行压缩,可以设置为 no 关闭此功能。
dbfilename:用于生成的快照文件的名字 ,默认为 dump.rdb。
dir:配置生成的快照文件存储的位置,默认为当前目录下。
- 主从复制触发
在主从复制过程中,如果从节点执行全量复制操作,主节点会自动执行 bgsave 命令,来生成 RDB 文件并发送给从节点。
- 执行特定命令触发
执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作。
- 关闭 Redis 触发
默认情况下,执行 shutdown 命令时,如果没有开启 AOF 持久化功能,则自动执行 bgsave。
1.3 触发方式二:手动触发
- save 命令
执行该命令会阻塞当前 Redis 服务,直到 RDB 快照生成完成为止。
这种方式在数据量大的时候可能会造成长时间阻塞,因此不建议在生产环境中使用。
示例命令:redis-cli save
。
- bgsave 命令
Redis 主进程会 fork 一个子进程来处理 RDB 快照生成任务,而主进程可以继续处理其他命令请求,即**"写时复制"(Copy-On-Write)**。
这种方式对主进程性能影响较小,但 fork 操作本身可能会有一定的性能开销。
示例命令:redis-cli bgsave
。
执行上述命令后,Redis 会返回"Background saving started"的消息,表示 RDB 快照正在生成中。当快照生成完成后,Redis 会返回"OK"消息,并更新相关的统计信息。
二、AOF(追加模式)
2.1 简介
Redis 的 AOF(Append Only File)持久化策略,通过记录服务器接收到的每个 set、del 等操作命令到日志文件中,当 Redis 重启时,它会重新执行这些命令来恢复数据。
- 工作原理
命令追加:Redis 服务器在执行写命令时,会将命令以协议格式追加到 AOF 缓冲区中。这些命令包括 SET、DEL 等对数据库进行修改的操作,而读操作不会被记录。
写入文件:AOF 缓冲区中的数据会被周期性地写入磁盘文件中的 AOF 文件。写入的频率可以通过配置文件中的 appendfsync 参数来设置,该参数决定了何时将缓冲区内容同步到磁盘上。
重写机制:随着时间的推移,AOF 文件可能会变得非常大,为了减小文件大小和提高恢复速度,Redis 提供了 AOF 文件重写功能。重写过程会创建一个新的 AOF 文件,将当前内存中的数据以命令序列的方式写入新文件,然后替换原有的 AOF 文件。重写过程中不包含对已过期或已被删除数据的写命令,因此可以显著减少 AOF 文件的大小。

注意:AOF 新文件,也是在 disk 磁盘上的。
- 配置选项
appendfsync:这个参数用于设置 AOF 持久化的同步策略,它有三个可选值:
- **always:每次写操作后同步(数据零丢失,性能最低)。**这种策略确保了最高的数据安全性,但会对性能产生较大影响,因为它需要在每次写操作后都等待磁盘写入完成。
- **everysec:每秒同步一次(默认策略)。**这是最常用的策略,它在性能和数据安全性之间取得了较好的平衡。Redis 每秒将 AOF 缓冲区的内容写入磁盘一次,这样即使在发生故障时,最多只会丢失最近一秒的数据。
- no:由操作系统决定同步时机。 这种策略效率最高,但对数据安全性的影响也最大。在这种模式下,Redis 不会主动进行磁盘同步操作,而是依赖操作系统的文件缓存机制来决定何时将数据写入磁盘。
auto-aof-rewrite-percentage:用于设置触发 AOF 重写的增长百分比。例如,如果将其设置为 100%,则表示当 AOF 文件的大小比上次重写后增长了 100% 时,就会触发 AOF 重写。
auto-aof-rewrite-min-size:用于设置触发 AOF 重写的最小文件大小。只有当 AOF 文件达到这个指定的大小以上时,才会考虑是否触发重写。
注意:auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 这两个配置项需要同时满足才会触发 AOF(Append Only File)重写操作。
- AOF 模式的优势
数据安全性高: 相较于 RDB,AOF 提供更高的数据安全性,尤其是在频繁更新的场景下。由于AOF是以追加方式记录操作日志,因此即使在崩溃后也能最大限度地恢复数据。即使中途服务器宕机,或者 AOF 文件出现了写入错误或者损坏,也可以通过 redis-check-aof 工具解决数据一致性问题,或者通过 redis-check-rdb 工具来从 AOF 文件中恢复 RDB 文件。
可读性好: AOF文件是一个文本文件,可以通过简单的文本编辑工具查看和修改,更加友好和可读。
**支持秒级同步:**根据配置文件中的 appendfsync 选项,有三种同步策略:always、everysec 和 no,可以按需灵活配置。
通过 redis-check-aof 工具来解决数据一致性问题的简单步骤:
- 备份原始AOF文件。避免修复过程中出现问题,破坏原始文件的状态,造成额外的损失。
- 检查 AOF 文件的损坏情况。工具会输出检查结果,显示文件中存在的错误类型、错误位置以及可能的修复建议。
- 修复 AOF 文件。根据检查结果选择合适的修复方法:如果AOF文件的错误较少且简单,可以尝试手动修复;对于更复杂的错误,可能需要使用专业的文本编辑工具或脚本进行处理。也可以使用 redis-check-aof 工具自动修复。执行带有 --fix 选项的 redis-check-aof 命令,工具会自动尝试修复文件中的错误。但需要注意,自动修复可能会导致一些数据丢失或不一致的情况。
- 验证修复后的 AOF 文件。启动 Redis 服务器并加载修复后的文件,确认数据能够正常加载。然后再检查数据完整性,可以通过执行一些查询操作或与备份数据进行比较,来验证修复后的AOF文件中的数据是否与预期一致。如果发现数据仍然存在问题,可能需要重新检查和修复AOF文件。
- AOF 模式的劣势
文件体积较大:由于 AOF 记录的是每一个写命令,所以其文件大小通常比 RDB 大很多。不过,Redis 支持 AOF 重写(rewrite),可以压缩 AOF 文件大小。
恢复速度较慢:与 RDB 相比,从 AOF 文件恢复数据的速度要慢一些,因为它需要重新执行所有的命令。
性能开销较高:AOF 持久化需要对每个写命令进行同步操作,而 RDB 持久化只需要定期执行快照操作。特别是在"always"同步策略下,AOF 持久化会显著降低 Redis 的吞吐量。
2.2 触发方式一:自动触发
自动触发依赖配置参数,当满足特定条件时,Redis 会自动执行 AOF 重写。
自动触发就是依赖 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 这两个配置项的值。
当两个配置项同时满足时,自动触发。
简单示例:
# 当 AOF 日志大小至少为 64mb,并且增长超过了上次重写后的 100% 时,触发 AOF 重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
2.3 触发方式二:手动触发
手动触发允许用户通过 Redis 命令主动执行 AOF 文件的重写操作。
使用bgrewriteaof
命令手动触发 AOF 重写。
- 大概工作流程
Fork 子进程:Redis 主进程会通过 fork() 创建一个子进程。
子进程生成新 AOF 文件:子进程基于当前内存数据生成一个新的紧凑 AOF 文件(临时文件)。
主进程处理新写入命令:在子进程生成新 AOF 文件期间,主进程继续处理客户端请求,并将新写入的命令暂存到 AOF 重写缓冲区(aof_rewrite_buf)。
合并数据:子进程完成新 AOF 文件后,主进程将重写缓冲区中的新命令追加到新文件中。
替换旧文件:新 AOF 文件生成后,替换旧的 AOF 文件,完成重写。
# 手动触发 AOF 重写
redis-cli BGREWRITEAOF
# 查看重写进度(可选)
redis-cli INFO persistence
三、混合模式(RDB + AOF)
3.1 简介
Redis 4.0 引入:允许在 AOF 重写时,将内存数据以 RDB 快照的形式写入 AOF 文件的开头,后面追加增量的 AOF 命令。
混合模式目的就是,结合 RDB 的快速恢复和 AOF 的数据完整性,使两者优势互补,以达到最佳效果。
- 工作原理
**AOF 重写触发:**当满足 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 条件时,生成混合 AOF 文件:
- RDB 快照部分:子进程将当前内存数据以 RDB 格式写入新文件的开头(aof-preamble)。
- AOF 增量部分:将重写期间的新写命令以 AOF 格式追加到文件末尾。
**文件替换:**新文件(如 appendonly.aof_tmp)原子替换旧的 AOF 文件。
- 数据恢复大致流程
加载 RDB 快照:快速恢复到重写时的内存状态。
重放 AOF 增量:应用新写入的命令,确保数据一致性。
例如,在一个数据库备份恢复的场景中,先加载RDB获取大部分数据,再通过AOF恢复近期的修改,确保数据的完整性。
- 混合模式的优势
恢复速度快:RDB 快照提供快速恢复基础,AOF 增量补全数据。
数据安全性高:AOF 记录所有写操作,减少数据丢失风险。
文件体积优化:RDB 部分压缩了冗余命令。
- 混合模式的劣势
文件结构复杂:混合文件需同时支持 RDB 和 AOF 格式解析。
磁盘空间需求:可能比纯 AOF 占用更多空间。
混合模式与两个单独模式的对比:
特性 | 纯 RDB | 纯 AOF | 混合模式 |
---|---|---|---|
恢复速度 | 快(二进制) | 慢(逐行解析) | 快(RDB 基础 + AOF 增量) |
数据丢失风险 | 快照间隔内可能丢失数据 | 根据同步策略(如 1 秒内) | 最小化丢失(AOF 保障) |
文件体积 | 小 | 大 | 中(RDB 压缩 + AOF 增量) |
适用场景 | 数据量小,对恢复速度要求高 | 数据量大,需高安全性 | 需平衡速度与数据完整性 |
3.2 配置方法
总共涉及四个配置项,如下:
# 启用 AOF:
appendonly yes
# 开启混合持久化:
aof-use-rdb-preamble yes
# 配置 AOF 重写条件:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
参考:https://blog.csdn.net/Seky_fei/article/details/106594029**https://tongyi.aliyun.com/qianwen/