redis的持久化

Redis 是内存数据库,数据默认存放在内存中。

一旦进程退出或服务器断电,内存数据全部丢失。持久化就是解决这个问题的机制。

Redis 提供两种核心持久化方案:RDBAOF

Redis 4.0 之后还支持混合持久化


一、RDB(Redis Database)快照

RDB 是将某一时刻的内存数据生成一个二进制快照文件dump.rdb),保存到磁盘上。

1、触发方式

方式 命令/配置 说明
手动触发 SAVE 阻塞主进程,直到快照完成。生产环境禁止使用
手动触发 BGSAVE 主进程 fork 出子进程,由子进程执行快照,主进程继续处理请求。
自动触发 save 900 1 配置文件中设置:900 秒内至少有 1 次写操作,自动触发 BGSAVE
自动触发 save 300 10 300 秒内至少有 10 次写操作。
自动触发 save 60 10000 60 秒内至少有 10000 次写操作。
其他触发 主从复制、执行 SHUTDOWN、执行 FLUSHALL 也会触发 RDB 生成。

2、执行流程(BGSAVE)

复制代码
1. 执行 BGSAVE
2. 主进程调用 fork() 创建子进程
   ├── 主进程:继续处理客户端请求
   └── 子进程:读取内存数据,写入临时 RDB 文件
3. 子进程写完临时文件后,原子替换旧的 dump.rdb

3、fork 与 Copy-On-Write

fork() 创建子进程时,操作系统使用写时复制(Copy-On-Write)

  • 子进程和父进程共享同一块物理内存页

  • 只有当父进程修改某页数据时,操作系统才会复制该页给父进程使用

  • 子进程看到的始终是 fork 瞬间的内存快照

这意味着:

  • BGSAVE 期间,Redis 的内存占用可能临时翻倍(如果写操作很频繁)

  • 如果数据修改量大,COW 开销不可忽视

4、RDB 文件结构

RDB 是一个紧凑的二进制文件,包含:

  • 文件头(魔数、版本号)

  • 数据库选择器

  • 键值对数据(经过压缩)

  • 校验和

5、RDB 的优缺点

优点 缺点
文件紧凑,体积小 无法做到实时持久化,两次快照之间可能丢数据
恢复速度快(直接加载二进制到内存) BGSAVE 时 fork 子进程有性能开销
适合备份、全量复制 如果数据量大,fork 可能耗时较长,阻塞主进程

二、AOF(Append Only File)日志

AOF 将 Redis 执行的每一条写命令 以日志形式追加写入文件。重启时重新执行这些命令即可恢复数据。

1、执行流程

复制代码
客户端发送写命令: SET key value
    ↓
Redis 服务端
    ├── 1. 执行命令,修改内存数据
    └── 2. 将命令追加到 AOF 缓冲区(aof_buf)
            ↓
    每隔一段时间(或每次事件循环)将缓冲区写入内核缓冲区
            ↓
    根据 appendfsync 策略,刷入磁盘

2、三种刷盘策略(appendfsync)

模式 说明 数据安全性 性能
always 每次写命令都 fsync 刷盘 最高,几乎不丢数据 最低,每条命令都写磁盘
everysec 每秒 fsync 一次(默认) 较好,最多丢 1 秒数据 较好,后台线程执行
no 由操作系统决定何时刷盘 最低,可能丢几十秒数据 最高

生产环境推荐 everysec,在性能和安全性之间取得平衡。

3、AOF 重写(Rewrite)

AOF 文件会不断膨胀。例如:

复制代码
RPUSH list a
RPUSH list b
RPUSH list c
LPOP list

这些命令可以合并为一条 RPUSH list b c,效果相同但日志更小。

AOF 重写就是干这件事:生成一个新的、更精简的 AOF 文件。

重写触发方式

方式 命令/配置
手动触发 BGREWRITEAOF
自动触发 auto-aof-rewrite-percentage 100 + auto-aof-rewrite-min-size 64mb

重写流程

复制代码
1. 触发 BGREWRITEAOF
2. 主进程 fork 子进程
   ├── 子进程:遍历当前内存数据,生成新的精简 AOF 文件
   └── 主进程:继续处理请求,同时将新命令写入 AOF 重写缓冲区
3. 子进程写完新 AOF 文件后,主进程将重写缓冲区的命令追加到新文件末尾
4. 原子替换旧 AOF 文件

4、AOF 的优缺点

优点 缺点
数据安全性高(alwayseverysec 文件体积大,是 RDB 的几倍到几十倍
可读性强(文本格式,可以手动查看/编辑) 恢复速度慢(要逐条重放命令)
支持实时持久化 刷盘操作有性能开销

三、RDB vs AOF 对比

维度 RDB AOF
文件格式 二进制快照 文本日志
文件体积
恢复速度 快(直接加载内存) 慢(逐条执行命令)
数据安全性 可能丢两次快照间的全部数据 最多丢 1 秒数据(everysec)
实时性 非实时 实时(always)或近实时(everysec)
可读性 不可读 可读可编辑
对性能影响 fork 时有短暂开销 持续刷盘开销

四、混合持久化(Redis 4.0+)

Redis 4.0 引入了混合持久化 ,试图结合 RDB 和 AOF 的优点。

1、原理

在 AOF 重写时:

  • 子进程先将当前内存数据以 RDB 格式写入新 AOF 文件的前半部分

  • 重写期间产生的新命令,以 AOF 格式追加到文件后半部分

最终文件结构:

复制代码
+-------------------+-------------------+
|   RDB 格式部分     |   AOF 格式部分     |
| (内存快照,二进制)  | (增量命令,文本)   |
+-------------------+-------------------+

2、恢复流程

复制代码
1. 先加载 RDB 部分(快速恢复大部分数据到内存)
2. 再执行 AOF 部分的增量命令(补全重写期间的数据)

3、开启方式

复制代码
aof-use-rdb-preamble yes

4、优势

方面 说明
恢复速度 比纯 AOF 快很多(RDB 部分直接加载)
文件体积 比纯 AOF 小(RDB 是二进制压缩的)
数据安全性 保留了 AOF 的增量特性,最多丢少量数据

五、生产环境配置建议

方案一:RDB + AOF 混合(推荐)

bash 复制代码
# 开启 AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# 开启 RDB(作为备份和快速恢复手段)
save 900 1
save 300 10
save 60 10000

# 开启混合持久化
aof-use-rdb-preamble yes

逻辑

  • AOF(everysec)保证数据安全,最多丢 1 秒

  • RDB 作为额外的备份副本,用于灾难恢复

  • AOF 重写时使用混合格式,兼顾恢复速度和文件大小

方案二:纯 RDB(数据可接受丢失的场景)

复制代码
appendonly no
save 900 1
save 300 10
save 60 10000

适用于缓存场景,数据可以从数据库重建,追求极致性能。

方案三:纯 AOF(数据绝不能丢的场景)

复制代码
appendonly yes
appendfsync always

适用于金融交易等场景,每条命令都刷盘,性能牺牲最大。


六、持久化相关的常见问题

1. fork 阻塞问题

BGSAVEBGREWRITEAOF 都需要 fork()。如果 Redis 实例内存很大(几十 GB),fork 操作可能耗时几百毫秒甚至几秒,期间主进程阻塞。

缓解方案

  • 控制单实例内存大小(建议不超过 10GB)

  • 使用 Redis 集群分片,降低单个节点的数据量

2. AOF 重写时的磁盘 IO 压力

重写期间,子进程大量写盘,可能和主进程的 fsync 竞争磁盘 IO。

缓解方案

  • 将 AOF 文件放在独立的磁盘或 SSD 上

  • 调整 no-appendfsync-on-rewrite yes:重写期间暂停 fsync,牺牲一点安全性换取性能

3. 持久化文件损坏

如果 AOF 文件末尾损坏(如写了一半断电),Redis 提供了修复工具:

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

RDB 文件损坏则较难修复,通常依赖备份副本。


七、总结

机制 一句话概括
RDB 定时拍内存快照,恢复快、文件小,但可能丢数据
AOF 记录每条写命令,数据安全、可实时持久化,但文件大、恢复慢
混合 AOF 重写时前半段用 RDB、后半段用 AOF,兼顾两者优点

核心选择逻辑

  • 能丢数据 → RDB

  • 不能丢数据 → AOF(everysec)

  • 又要快又要安全 → RDB + AOF 混合

相关推荐
添砖java‘’1 小时前
Redis中常用数据结构
数据库·redis·缓存
玛丽莲茼蒿7 小时前
Redis(六)—— Redis高级
数据库·redis·缓存
渣渣盟7 小时前
Flink 写入 Redis 实战:数据模型选型、连接池调优与常见坑
大数据·redis·flink
旺旺仙贝呦8 小时前
MySQL__MongoDB__Redis 入门
redis·mysql·mongodb
陈聪.8 小时前
企业级 NoSQL 数据库 Redis 核心知识整理
数据库·redis·nosql
To_OC18 小时前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
lv__pf1 天前
redis【msb 2026金三银四redis上】
数据库·redis·缓存
spter。1 天前
一次 Redis SETNX 的小插曲,我重新理解了原子性
前端·redis·bootstrap
霸道流氓气质1 天前
Redis Pub/Sub — 概念、原理、场景与代码示例
数据库·redis·缓存