Redis的持久化机制有哪些?
重要内容
Redis提供两种主要的持久化机制
RDB (Redis Database)快照:通过生成某一时刻的数据快照来实现持久化的,可以在特定时间间隔内保存数据的快照
AOF(Append Only File)日志:通过将每个写操作追加到日志文件中实现持久化,支持将所有写操作记录下来以便恢复
RDB和AOF的混合持久化机制 (Redis 4.0+):结合RDB和AOF,生成 RDB快照 + 增量AOF日志 的混合文件(平衡两者优缺点)
拓展知识
RDB 持久化
通过创建快照来获取内存某个时间点上的副本,利用快照可以进行方便地进行主从复制,默认快照文件为 dump.rdb
触发方式
- 手动触发:执行
SAVE(阻塞主线程)或BGSAVE(后台异步生成快照) - 自动触发:根据 redis.conf 配置(如
save 900 1表示900秒内至少1次修改)自动执行BGSAVE
BGSAVE 流程(重点)
大致流程
-
客户端发起BGSAVE命令
-
主进程检查现有子进程(否存在正在执行备份的子进程),如果存在就返回错误信息
-
父进程fork生成子进程
Fork 操作利用了写时复制:在子进程创建时,它不会直接将主进程地址空间全部复制,而是共享同一个内存。之后如果任意一个进程需要对内存进行修改操作,内存会重新复制一份提供给修改的进程单独使用
-
子进程生成内存快照
-
子进程原子替换旧RDB文件
-
子进程发送完成信号并更新统计信息
流程图
%%{ init: { 'theme': 'default', 'themeVariables': { 'fontSize': '32px' } } }%%
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:4px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:4px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:4px
A([开始]):::startend --> B(客户端发送 BGSAVE 命令):::process
B --> C{是否已有 RDB 子进程在运行?}:::decision
C -->|是| D(返回错误信息):::process
C -->|否| E(主进程 fork 子进程):::process
E --> F{fork 是否成功?}:::decision
F -->|否| G(返回错误信息):::process
F -->|是| H(主进程继续处理客户端请求):::process
F -->|是| I(子进程开始将数据写入临时 RDB 文件):::process
I --> J{数据写入是否完成?}:::decision
J -->|否| I
J -->|是| K(子进程用临时 RDB 文件替换旧的 RDB 文件):::process
K --> L(子进程向主进程发送完成信号):::process
L --> M(主进程更新统计信息):::process
N([结束]):::startend
D --> N
G --> N
M --> N
优点
- 恢复速度快:直接加载二进制快照文件(
.rdb),适合大规模数据恢复 - 文件紧凑:快照文件体积小,便于备份和灾难恢复
- 性能影响低:
BGSAVE使用子进程生成快照,主进程继续处理请求
缺点
- 数据丢失风险:若两次快照之间发生故障,可能丢失最后一次快照后的所有数据
AOF 持久化
AOF 持久化机制是指将Redis写命令以追加的形式写入到磁盘中的AOF文件,AOF文件记录了Redis在内存中的操作过程,只要在Redis重启后重新执行AOF文件中的写命令即可将数据恢复到内存中
同步策略(通过 appendfsync 配置)
- no:由操作系统决定何时同步(性能高,风险大)
- everysec(默认):每秒同步一次(平衡性能与安全)
- always:每次写操作都同步(最安全,性能最低)
重写机制
文件随着写操作的增加会不断变大,过大的AOF文件会导致恢复速度变慢,并消耗大量磁盘空间。所以,Rdis提供了 AOF重写机制,即对AOF文件进行压缩,通过最少的命令来重新生成一个等效的AOF文件
触发方式
-
手动触发:使用BGREWRITEAOF命令可以手动触发AOF重写
-
自动触发:通过配置文件中的参数控制自动触发条件
auto-aof-rewrite-percentage 100 # 触发重写百分比 (如果设置为0,将禁用AOF自动重写功能) auto-aof-rewrite-min-size 64mb # 触发自动重写的最低文件体积(小于64MB不自动重写)
重写流程图
%%{ init: { 'theme': 'default', 'themeVariables': { 'fontSize': '36px' } } }%%
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:4px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:4px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:4px
A([开始]):::startend --> B(客户端发送 BGREWRITEAOF 命令 或 达到自动重写条件):::process
B --> C{是否已有 AOF 重写子进程在运行?}:::decision
C -->|是| D(返回错误信息):::process
C -->|否| E(主进程 fork 子进程):::process
E --> F{fork 是否成功?}:::decision
F -->|否| G(返回错误信息):::process
F -->|是| H(主进程继续处理客户端请求,并将新的写命令追加到 AOF 缓冲区和 AOF 重写缓冲区):::process
F -->|是| I(子进程根据内存中的数据生成新的 AOF 文件):::process
I --> J{新 AOF 文件生成是否完成?}:::decision
J -->|否| I
J -->|是| K(主进程将 AOF 重写缓冲区的内容追加到新 AOF 文件):::process
K --> L(用新 AOF 文件替换旧的 AOF 文件):::process
L --> M(更新相关统计信息):::process
N([结束]):::startend
D --> N
G --> N
M --> N
优点
- 数据安全性高:最多丢失1秒(或更少)的数据(取决于同步策略)
- 可读性强:AOF文件为文本格式,便于人工分析或修复
缺点
- 文件体积大:AOF文件通常比RDB大,尤其在未重写时
- 恢复速度慢:重放所有命令恢复数据,耗时长于RDB
混合持久化(Redis 4.0+)
结合RDB和AOF持久化,生成 RDB快照 + 增量AOF日志 的混合文件(.aof)
开启方式:使用命令 config set aof-use-rdb-preamble yes来开启
触发条件:执行AOF重写(BGREWRITEAOF)时,先以RDB格式保存当前快照,后续增量命令以AOF格式追加
- 数据恢复直接加载RDB部分,再重放增量AOF命令,兼顾速度和数据完整性