文章目录
-
前言
一、RDB 持久化(快照持久化)
1. 定义
2. RDB 触发机制
(1)手动触发
(2)自动触发
3. RDB 持久化流程
4. RDB 核心配置
5. RDB 优缺点
二、AOF 持久化(日志持久化)
1. 定义
2. AOF 核心原理
3. AOF 的 fsync 策略(关键配置)
4. AOF 重写(解决文件膨胀问题)
(1)为什么需要重写?
(2)重写触发方式
(3)重写流程
5. AOF 核心配置
6. AOF 优缺点
三、混合持久化(Redis 4.0+)
1. 定义与目的
2. 混合持久化原理
3. 核心配置
4. 混合持久化优势
四、RDB vs AOF vs 混合持久化 对比
五、持久化方案选择建议
六、关键注意事项
前言
Redis 是一款内存数据库,所有数据默认存储在内存中。虽然内存操作速度极快,但一旦 Redis 服务重启、进程崩溃或服务器断电,内存中的数据会全部丢失。为解决这一问题,Redis 提供了持久化机制—— 将内存中的数据定期 / 实时写入磁盘,确保数据在故障后可恢复。
Redis 支持三种核心持久化方式:RDB(Redis Database)、AOF(Append Only File) 和 混合持久化(RDB + AOF,Redis 4.0+ 引入)。下面逐一详解其原理、配置、优缺点及适用场景。
一、RDB 持久化(快照持久化)
1. 定义
RDB 是 Redis 默认的持久化方式,其核心是在指定时间点生成内存中所有数据的 “快照”(二进制压缩文件),并将快照保存到磁盘(默认文件名为 dump.rdb
)。当 Redis 重启时,可通过加载该快照文件恢复数据。
2. RDB 触发机制
RDB 触发分为手动触发和自动触发两种方式,核心差异在于是否阻塞 Redis 主进程。
(1)手动触发
手动触发需通过 Redis 命令执行,主要有两个命令:
-
save
命令:
直接由 Redis 主进程执行快照生成,期间会阻塞所有客户端请求(主进程无法处理其他命令),直到快照完成。- 适用场景:仅用于测试或数据量极小的场景,生产环境严禁使用(会导致服务不可用)。
-
bgsave
命令:
主进程会先fork()
一个子进程,由子进程负责生成快照文件,主进程继续处理客户端请求(非阻塞)。- 核心原理:
fork()
子进程时采用 写时复制(Copy-On-Write, COW) 机制 —— 子进程生成快照期间,主进程若修改数据,会先复制该数据的内存页(子进程仍使用旧数据页),确保快照数据的一致性。 - 适用场景:生产环境推荐的手动触发方式。
- 核心原理:
(2)自动触发
Redis 配置文件(redis.conf
)中通过 save
指令定义 “时间窗口 + 写操作次数” 的触发条件,满足条件时自动执行 bgsave
。
示例配置(默认配置):
# 格式:save <seconds> <changes>
save 900 1 # 900秒内(15分钟)至少有1次写操作,触发bgsave
save 300 10 # 300秒内(5分钟)至少有10次写操作,触发bgsave
save 60 10000 # 60秒内至少有10000次写操作,触发bgsave
- 若需禁用自动 RDB,可删除所有
save
配置,或添加save ""
。
3. RDB 持久化流程
- 触发
bgsave
(手动或自动),主进程fork()
子进程(此时主进程短暂阻塞,时间取决于内存大小,通常毫秒级)。 - 子进程遍历 Redis 内存中的数据,将其写入临时快照文件(如
temp-dump.rdb
)。 - 子进程写完所有数据后,用临时文件替换旧的
dump.rdb
文件(原子操作,避免文件损坏)。 - 子进程退出,主进程记录快照完成日志。
4. RDB 核心配置
配置项 | 说明 | 默认值 |
---|---|---|
save <sec> <n> | 自动触发 RDB 的条件(可配置多个) | 见上文示例 |
dbfilename | RDB 快照文件名称 | dump.rdb |
dir | RDB/AOF 文件的存储目录(需指定绝对路径) | ./ (当前目录) |
rdbcompression | 是否对 RDB 文件进行 LZF 压缩(压缩会消耗 CPU,但减少文件大小) | yes |
rdbchecksum | 是否对 RDB 文件进行 CRC64 校验(校验会消耗 CPU,但确保文件完整性) | yes |
stop-writes-on-bgsave-error | 若 bgsave 失败,是否停止 Redis 写操作(防止数据不一致) | yes |
5. RDB 优缺点
优点 | 缺点 |
---|---|
1. 文件小:二进制压缩格式,占用磁盘空间少。 | 1. 数据丢失风险高:两次快照间的写数据会丢失(如配置 save 60 10000 ,若 60 秒内服务崩溃,10000 次操作前的数据丢)。 |
2. 恢复速度快:加载二进制文件无需解析,适合大规模数据恢复。 | 2. fork 开销:bgsave 时 fork 子进程会占用与主进程相同的内存页(COW 机制下实际仅复制修改页,但内存峰值仍需关注)。 |
3. 不影响主进程:bgsave 由子进程执行,主进程可正常处理请求。 | 3. 不适用于实时持久化:无法做到 “每写一次就持久化”,满足不了高数据安全性需求。 |
二、AOF 持久化(日志持久化)
1. 定义
AOF(Append Only File)是基于 “写操作日志” 的持久化方式——Redis 将每一条修改数据的命令(如 SET
、HSET
、LPUSH
等)以文本格式(或二进制,Redis 7.0+ 支持)追加到 AOF 文件中,而非记录数据快照。当 Redis 重启时,通过 “回放” AOF 文件中的所有命令,重新构建内存数据。
2. AOF 核心原理
AOF 的核心是 “追加(Append)而非修改”:
- 所有写命令先写入 内存缓冲区(aof_buf),再根据配置的
fsync
策略将缓冲区数据刷到磁盘(避免频繁磁盘 I/O 影响性能)。 - AOF 文件始终以 “追加” 模式写入,不会修改已有内容,确保日志文件不会因崩溃而损坏(即使崩溃,仅丢失最后未刷盘的命令)。
3. AOF 的 fsync
策略(关键配置)
fsync
是操作系统调用,用于将内存缓冲区的数据强制刷到磁盘(确保数据真正写入硬件)。AOF 通过 appendfsync
配置控制 fsync
频率,平衡 “数据安全性” 和 “性能”:
配置值 | 说明 | 安全性 | 性能 |
---|---|---|---|
always | 每执行一条写命令,立即 fsync 刷盘。 | 最高 | 最低 |
everysec | 每秒执行一次 fsync (默认配置),缓冲区数据累积 1 秒后刷盘。 | 较高 | 较高 |
no | Redis 不主动 fsync ,由操作系统决定何时刷盘(通常依赖系统缓存,默认 30 秒)。 | 最低 | 最高 |
- 生产环境推荐
everysec
:仅可能丢失 1 秒内的数据,性能接近no
,安全性满足大部分场景。
4. AOF 重写(解决文件膨胀问题)
(1)为什么需要重写?
AOF 文件会不断追加命令,若频繁执行 INCR count
这类命令,AOF 文件中会积累大量重复命令(如 INCR count
1000 次,实际只需 1 条 SET count 1000
即可恢复数据),导致文件急剧膨胀,占用磁盘空间且恢复速度变慢。
AOF 重写的核心是 **“压缩命令日志”**:不读取旧 AOF 文件,而是直接遍历当前内存中的数据,生成 “重建该数据所需的最少命令”,并写入新的 AOF 文件,替换旧文件。
(2)重写触发方式
- 手动触发:执行
bgrewriteaof
命令,主进程fork()
子进程负责重写,主进程继续处理请求(非阻塞)。 - 自动触发:通过配置两个参数,满足条件时自动执行
bgrewriteaof
:auto-aof-rewrite-percentage 100 # AOF 文件大小比上次重写后增长100%(即翻倍) auto-aof-rewrite-min-size 64mb # AOF 文件最小大小达到64MB(避免小文件频繁重写)
(3)重写流程
- 主进程
fork()
子进程,子进程开始遍历内存数据,生成新 AOF 临时文件。 - 主进程继续处理请求:新的写命令一方面追加到旧 AOF 文件(确保重写期间数据不丢失),另一方面写入 AOF 重写缓冲区(aof_rewrite_buf)。
- 子进程完成重写后,主进程将
aof_rewrite_buf
中的命令追加到新 AOF 文件。 - 用新 AOF 文件替换旧文件,重写完成。
5. AOF 核心配置
配置项 | 说明 | 默认值 |
---|---|---|
appendonly | 是否开启 AOF 持久化(默认关闭,需手动设为 yes ) | no |
appendfilename | AOF 文件名称 | appendonly.aof |
dir | AOF 文件存储目录(与 RDB 共享,需绝对路径) | ./ |
appendfsync | fsync 策略(always /everysec /no ) | everysec |
auto-aof-rewrite-percentage | 自动重写的文件大小增长率 | 100 |
auto-aof-rewrite-min-size | 自动重写的文件最小大小 | 64mb |
aof-load-truncated | 若 AOF 文件末尾有损坏(如崩溃导致),是否仍加载可用部分(默认开启) | yes |
6. AOF 优缺点
优点 | 缺点 |
---|---|
1. 数据安全性高:everysec 策略仅丢 1 秒数据,always 可做到不丢数据。 | 1. 文件体积大:文本日志比 RDB 二进制文件大,占用更多磁盘空间。 |
2. 日志可读性强:文本格式可直接查看 / 修改(如删除误操作的命令)。 | 2. 恢复速度慢:加载时需解析并执行所有命令,大规模数据恢复比 RDB 慢。 |
3. 无数据丢失风险:适合对数据安全性要求高的场景。 | 3. fsync 开销:always 策略会频繁触发磁盘 I/O,性能损耗较大。 |
4. 重写机制优化:通过重写解决文件膨胀问题。 | 4. 兼容性问题:旧版本 Redis 可能不支持新版本 AOF 文件的某些命令格式。 |
三、混合持久化(Redis 4.0+)
1. 定义与目的
单独使用 RDB 或 AOF 都有明显缺陷:
- RDB 恢复快但数据丢失多;
- AOF 数据全但恢复慢(尤其文件大时)。
混合持久化(RDB + AOF)是 Redis 4.0 引入的解决方案:将 AOF 文件分为两部分:
- 开头部分:RDB 二进制快照(记录某一时间点的全量数据);
- 末尾部分:增量 AOF 日志(记录 RDB 快照之后的所有写命令)。
重启时,Redis 先加载 RDB 快照(快速恢复全量数据),再回放末尾的 AOF 日志(恢复增量数据),兼顾 “恢复速度” 和 “数据完整性”。
2. 混合持久化原理
- 开启混合持久化后,执行
bgrewriteaof
(手动或自动)时,子进程会先生成 RDB 二进制数据,写入新 AOF 文件开头; - 然后将重写期间的增量命令(
aof_rewrite_buf
)以 AOF 格式追加到新文件末尾; - 最终新 AOF 文件同时包含 RDB 快照和 AOF 日志,替换旧 AOF 文件。
3. 核心配置
Redis 4.0+ 需手动开启,Redis 5.0+ 默认为开启:
aof-use-rdb-preamble yes # yes:开启混合持久化;no:纯 AOF 模式
4. 混合持久化优势
- 恢复速度快:加载 RDB 快照比纯 AOF 回放命令快一个数量级;
- 数据完整性高:增量 AOF 日志确保 RDB 之后的数据不丢失;
- 文件体积适中:RDB 压缩 + AOF 增量,比纯 AOF 文件小。
四、RDB vs AOF vs 混合持久化 对比
对比维度 | RDB | AOF(纯) | 混合持久化(RDB+AOF) |
---|---|---|---|
持久化方式 | 二进制快照 | 写命令日志(追加) | RDB 快照 + AOF 增量日志 |
数据完整性 | 低(丢失两次快照间数据) | 高(最多丢 1 秒数据) | 高(同 AOF) |
文件大小 | 小(压缩) | 大(文本 / 二进制) | 中(RDB 压缩 + AOF 增量) |
恢复速度 | 快 | 慢 | 快(接近 RDB) |
性能影响 | 低(bgsave 子进程) | 中(fsync 策略) | 中(同 AOF) |
适用场景 | 大规模数据备份、恢复 | 高数据安全性需求 | 生产环境默认推荐 |
五、持久化方案选择建议
-
生产环境首选:混合持久化
兼顾 RDB 的 “快速恢复” 和 AOF 的 “高数据完整性”,是 Redis 5.0+ 推荐的默认方案,适合 90% 以上的业务场景。 -
仅用 RDB 的场景
- 数据允许丢失几分钟(如非核心缓存数据);
- 需频繁备份 / 恢复大规模数据(如每日全量备份);
- 对 Redis 性能要求极高,无法接受 AOF 的
fsync
开销。
-
仅用 AOF 的场景
- 数据绝对不允许丢失(如金融交易数据),需配置
appendfsync always
; - 需通过 AOF 日志排查历史操作(如定位误删数据的命令)。
- 数据绝对不允许丢失(如金融交易数据),需配置
-
禁用持久化的场景
- Redis 仅作为纯缓存(数据可从后端数据库重建);
- 测试环境,无需保留数据。
六、关键注意事项
-
持久化文件备份
- 定期将
dump.rdb
和appendonly.aof
复制到异地存储(如云存储、另一台服务器),防止单磁盘故障导致文件丢失。 - 备份时建议先执行
bgsave
/bgrewriteaof
,确保备份的是完整文件。
- 定期将
-
避免持久化文件与 Redis 同磁盘
- 若 Redis 数据和持久化文件存于同一磁盘,磁盘满时会导致 Redis 无法写入数据,建议分开存储。
-
定期测试恢复流程
- 模拟故障场景(如删除内存数据后重启 Redis),验证持久化文件能否正常加载,避免文件损坏或配置错误导致恢复失败。
-
内存与持久化配合
- 若 Redis 内存过大(如 10GB+),
bgsave
时fork
子进程可能导致内存峰值过高,需配置vm.overcommit_memory = 1
(允许操作系统超分配内存),避免fork
失败。
- 若 Redis 内存过大(如 10GB+),
总结
Redis 持久化用于内存数据落盘防丢失,核心有三种方案:
- RDB:默认快照式,文件小、恢复快,但两次快照间数据易丢失;
- AOF:需手动开启,记录写命令,数据安全(最多丢 1 秒),但文件大、恢复慢;
- 混合持久化(4.0+):结合 RDB 快恢复与 AOF 高安全,生产环境首选。
选择:生产优先混合,数据允许丢失用 RDB,绝对不丢用 AOF;需定期备份文件、测试恢复。