Redis 持久化机制:RDB 和 AOF

什么是持久化

Redis 是内存数据库,数据全部存储在内存中,因此一旦:

  • Redis 进程崩溃

  • 系统断电

  • 操作系统重启

内存数据会全部丢失。

为解决这个问题,Redis 提供了两种持久化方式:

1. RDB(快照 Snapshot)

  • 把某个时间点的内存数据完整写入磁盘

  • 生成 dump.rdb

适合用于冷备、主从同步、定期备份。

2. AOF(Append Only File)

  • 以日志的方式记录所有写操作(set/incr/...)

  • 通过重放日志恢复数据

适合追求数据最小丢失的场景。


RDB(快照持久化)

RDB工作原理

Redis 会在某个时间点把当前内存数据做一份快照保存到磁盘:

生成的文件:

复制代码
dump.rdb

采用二进制格式,体积较小,恢复速度快。


SAVE vs BGSAVE

我们可以主动使用命令save和bgsave进行持久化

SAVE(阻塞式)

复制代码
SAVE
  • 由主线程执行

  • 会阻塞 Redis,直到操作完成(不推荐)

BGSAVE(后台执行)

复制代码
BGSAVE
  • Redis 主线程 fork 出子进程

  • 子进程把数据写入 dump.rdb

  • 主线程继续处理业务读写(推荐)

主进程如果在 fork() 子进程之后继续写入新的数据,不会影响正在生成的 RDB 文件内容,但会产生额外的内存开销(Copy-On-Write 机制导致)

Redis 使用 Linux 的 Copy-On-Write(COW) 技术:

  • fork 后,父子进程共享相同的内存页(不复制)

  • 只有当主进程写某个 key 时,该内存页才会被复制

这意味着:

1. 子进程能继续使用"原来的旧内存页"写 RDB

2. 主进程则在写入时复制内存页,不影响子进程

如果 BGSAVE 期间写入量很大:

  • 会触发大量的内存页复制

  • Redis 内存使用可能短时间上升

举例:

如果 1GB 的数据中有 200MB 在 BGSAVE 期间被修改

→ Redis 需要额外复制 200MB

这是 BGSAVE 的主要代价。所以高写入业务:谨慎使用频繁 RDB


自动触发规则

redis.conf 中:

复制代码
save 900 1        # 900 秒内至少 1 次写操作
save 300 10       # 300 秒内至少 10 次写操作
save 60 10000     # 60 秒内至少 10000 次写操作

含义:满足任意一个条件都会触发 RDB。

禁用 RDB:

复制代码
save ""

RDB 文件位置与配置

redis.conf 中:

复制代码
dbfilename dump.rdb          # 文件名
dir /var/lib/redis           # 保存目录

查看运行时目录:

复制代码
CONFIG GET dir

RDB 优缺点

优点

  • 恢复速度快(文件小)

  • 对性能影响小(fork + 子进程写)

  • 文件适合作为冷备、主从同步

缺点

  • 不够实时,可能丢失几分钟数据

  • 文件为二进制,无法阅读

  • fork 过程中需要额外内存


AOF(追加日志持久化)

AOF工作原理

AOF 会把 Redis 的写命令追加记录到文件中:

复制代码
SET a 1
INCR b
LPUSH list 10

日志文件:

复制代码
appendonly.aof

Redis 重启时,按日志顺序重放命令恢复数据。


AOF 写回策略

配置项:

复制代码
appendfsync always
appendfsync everysec
appendfsync no

1. always

  • 每条写命令都 fsync,数据最安全

  • 性能最差

2. everysec(默认)

  • 每秒 fsync 一次

  • 性能与安全性折中

  • 最常用

3. no

  • 不主动 fsync,交给操作系统

  • 性能最好,安全性最差


AOF 文件位置与配置

在 redis.conf 中打开 AOF:

复制代码
appendonly yes
appendfilename "appendonly.aof"
dir /var/lib/redis

AOF 重写机制(Rewrite)

随着运行时间增加,AOF 会变得很大,比如:

复制代码
SET a 1
SET a 2
SET a 3

同一个key多次重复set,其实我们只需要保留最后一个就可以,前面的命令没有必要保留,rewrite机制仅保留必要命令:

复制代码
SET a 3

Redis 会:

  • fork 出子进程

  • 子进程根据当前内存数据生成一个更小的 AOF 文件

  • 不影响主线程处理请求

相关配置:

复制代码
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

含义:

  • 当 AOF 文件大小超过上次重写后大小的 100% 且至少 64MB

    → 触发自动重写


AOF 优缺点

优点

  • 最安全的持久化方式(最多丢失 1 秒)

  • 文本日志,可读、可手工修改

  • 重写机制减少文件大小

缺点

  • 文件普遍比 RDB 大

  • 恢复速度慢(需要重放大量命令)

  • 写性能比 RDB 开销更大


RDB 与 AOF 对比总结

特性 RDB AOF
数据安全性 可能丢失几分钟 最多丢失 1 秒
性能影响 中等
文件大小
恢复速度
可读性 不可读 可读
使用场景 定期冷备、主从同步 高安全、高可靠

RDB + AOF 混合持久化

Redis 支持同时启用:

复制代码
save 900 1
appendonly yes
appendfsync everysec

Redis 重启时优先使用 AOF 恢复(因为数据更新更新)。

这种组合:

  • RDB 作为完整快照

  • AOF 作为增量日志

  • 兼具速度与安全性


持久化文件恢复流程

恢复 RDB:

  1. 停止 Redis

  2. dump.rdb 放到配置的 dir 目录

  3. 启动 Redis

恢复 AOF:

  1. 停止 Redis

  2. 放置 appendonly.aof

  3. 若文件损坏可修复:

    复制代码
    redis-check-aof --fix appendonly.aof
  4. 启动 Redis

同时存在 RDB + AOF:

  • Redis 会优先 AOF 恢复

原因:数据更新更实时。


常见问题 FAQ

1. RDB 会阻塞 Redis 吗?

  • SAVE 会

  • BGSAVE 不会(使用子进程)

2. AOF 重写会阻塞吗?

不会,重写过程由子进程执行。

3. AOF 文件损坏怎么办?

复制代码
redis-check-aof --fix

4. RDB 文件损坏怎么办?

无法修复,只能使用备份。

5. 启用 AOF 会影响性能吗?

会有一定影响,但一般可接受,尤其是 everysec 策略。


总结

Redis 提供两种持久化方式:

RDB

  • 易于备份

  • 性能好

  • 快速恢复

AOF

  • 数据最安全

  • 可读可编辑

  • 更适合生产环境

推荐组合使用:

RDB + AOF(everysec)

兼具:

  • 安全性

  • 性能

  • 恢复速度

相关推荐
ANYOLY3 小时前
Redis 面试题库
java·redis·面试
小马爱打代码3 小时前
SpringBoot + Quartz + Redis:分布式任务调度系统 - 从架构设计到企业级落地
spring boot·redis·分布式
逻极4 小时前
Redis Queue (RQ) 核心原理:轻量任务队列的设计与实践(一句话讲透核心本质)
数据库·redis·bootstrap
q***51894 小时前
ubuntu 安装 Redis
linux·redis·ubuntu
2401_837088504 小时前
Redisson的锁重试和WatchDog机制
redis
q***31834 小时前
Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)
数据库·redis·缓存
梁bk6 小时前
Redis 多级缓存架构学习笔记
redis·缓存·架构
q***18849 小时前
Ubuntu上安装、使用Redis的详细教程
redis·ubuntu·bootstrap
q***656910 小时前
Windows环境下安装Redis并设置Redis开机自启
数据库·windows·redis