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 10300 秒内至少有 10 次写操作。
自动触发save 60 1000060 秒内至少有 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 对比

维度RDBAOF
文件格式二进制快照文本日志
文件体积
恢复速度快(直接加载内存)慢(逐条执行命令)
数据安全性可能丢两次快照间的全部数据最多丢 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 混合(推荐)

# 开启 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 混合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值