大数据-46 Redis RDB 持久化机制详解:原理、配置与优缺点解析

170 阅读12分钟

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-30-新发布【1T 万亿】参数量大模型!Kimi‑K2开源大模型解读与实践,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月16日更新到: Java-74 深入浅出 RPC Dubbo Admin可视化管理 安装使用 源码编译、Docker启动 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

在这里插入图片描述

RDB(Redis Database)是 Redis 默认的持久化方式,通过定期生成内存快照将数据保存为二进制文件 dump.rdb。当持久化触发时,Redis 主进程会 fork 子进程,子进程将当前数据写入临时文件并原子性替换旧文件,最大限度减少对主线程的影响。RDB适用于灾难恢复和大数据量的快速重载,具备文件小、恢复快、性能影响小的优势。但也存在数据不完整的风险——可能丢失最后一次快照之后的更新数据。RDB常配合 AOF 使用,在保证恢复速度的同时增强数据安全性。Redis 4.0 之后还支持混合持久化模式,兼具两者优点。

章节内容

上节完成了的内容如下:

  • Redis 持久化原因
  • Redis 持久化机制 RDB AOF
  • 基础概念、适用场景等

在这里插入图片描述

RDB (Redis DataBase)

RDB(Redis DataBase)是Redis默认的持久化存储方式。它通过创建数据快照(snapshotting)的方式将内存中的数据定期保存到磁盘上。这种机制类似于给数据库拍一张瞬间的照片,保存当前时刻的所有数据状态。

工作原理

当RDB持久化被触发时,Redis会:

  1. 主进程fork出一个子进程
  2. 子进程将当前内存中的数据写入临时RDB文件
  3. 写入完成后替换旧的RDB文件
  4. 整个过程主进程继续处理客户端请求(仅在fork时短暂阻塞)

触发方式

自动触发

  • 符合redis.conf中配置的快照规则(save指令)
  • 当Redis正常关闭时(shutdown命令)

手动触发

  • 执行SAVE命令(同步操作,会阻塞所有客户端请求)
  • 执行BGSAVE命令(异步操作,后台执行)
  • 执行FLUSHALL命令(会先触发RDB保存)

特殊场景

  • 主从复制时,主节点首次同步数据给从节点
  • 当没有AOF持久化时,重启Redis会加载最近的RDB文件

配置参数

在redis.conf配置文件中,RDB相关的核心配置包括:

# 禁用RDB持久化
save ""

# 触发条件配置(时间窗口 修改键数)
save 900 1    # 15分钟内至少1个键被修改
save 300 10   # 5分钟内至少10个键被修改
save 60 10000 # 1分钟内至少10000个键被修改

# RDB文件名称
dbfilename dump.rdb

# 工作目录(RDB文件存储路径)
dir /var/lib/redis

# 是否压缩RDB文件(默认yes
rdbcompression yes

# 是否校验RDB文件(默认yes
rdbchecksum yes

优缺点

优点

  • 全量备份,适合灾难恢复
  • 文件紧凑,占用空间小
  • 恢复大数据集时比AOF快
  • 最大化Redis性能(子进程执行持久化)

缺点

  • 可能丢失最后一次快照后的数据
  • 数据集较大时fork操作可能耗时
  • 频繁保存会影响性能

显式触发

bgsave

执行流程

在这里插入图片描述

Redis 的 bgsave 过程详解

1. 父进程的初始检查

Redis 在执行 bgsave 命令时,父进程首先会进行状态检查:

  • 检查当前是否有正在执行的子进程(如 Save、bgsave 或 bgrewriteaof)
  • 如果存在活跃的子进程,bgsave 会立即返回错误信息
  • 这个检查是为了避免同时执行多个磁盘 I/O 密集型操作导致性能下降

2. 父进程的 fork 操作

当确认可以执行 bgsave 后:

  • 父进程调用 fork() 系统调用创建子进程
  • 在 fork 操作期间,父进程会完全阻塞
  • 这个阻塞时间取决于 Redis 实例的内存大小(通常几毫秒到几百毫秒)
  • 在此期间,Redis 无法处理任何客户端命令,会出现短暂的不可用

3. fork 完成后的处理

fork 操作完成后:

  • 父进程立即恢复运行,返回 "Background saving started" 响应
  • 从此刻起,父进程可以正常处理所有客户端请求
  • 父进程会记录 bgsave 的开始时间等统计信息

4. 子进程的 RDB 生成过程

子进程的工作流程:

  1. 基于 fork 时获取的父进程内存快照开始工作
  2. 将内存数据序列化为 RDB 格式,写入临时文件(默认名为 temp-[pid].rdb)
  3. 使用原子性操作(rename)将临时文件替换旧的 dump.rdb 文件
  4. 期间如果发生错误,会删除临时文件并记录错误日志

5. 完成通知与统计更新

完成 RDB 生成后:

  • 子进程通过进程间通信向父进程发送完成信号
  • 父进程收到信号后:
    • 更新最后一次成功保存的时间戳
    • 记录持久化耗时等信息
    • 清理相关资源
  • 子进程随后正常退出

注意事项

  • 整个过程中,只有 fork 阶段会阻塞 Redis
  • RDB 生成期间的内存开销主要是写时复制(Copy-on-Write)带来的
  • 如果 Redis 内存数据很大,fork 操作可能会很耗时
  • 生产环境建议在低峰期执行 bgsave,并监控持久化耗时

文件结构

在这里插入图片描述

  • 头部 5字节固定位 REDIS
  • 4字节 RDB 版本号
  • 辅助字段 以 KEY-VALUE
  • 存储数据库号码
  • 字典大小
  • 过期 KEY
  • 主要数据 以 KEY-VALUE
  • 结束标志
  • 校验和,看文件是否存坏,是否被修改

RDB优点

  • RDB是二进制压缩文件,采用LZF压缩算法进行压缩,占用空间小(通常只有原数据的1/4大小),便于网络传输和备份存储
  • 主进程Fork子进程进行持久化操作:
    • 子进程完成持久化工作,主进程继续处理命令请求
    • 可以最大化Redis性能,避免持久化操作影响服务响应
    • 注意事项:主进程内存占用不能太大,否则fork操作会:
      • 消耗较多CPU资源
      • 导致服务短暂阻塞(通常几十毫秒到几百毫秒)
      • 在虚拟机环境下问题更明显

RDB缺点

  • 不保证数据的完整性
    • 采用定时快照机制,两次快照之间的数据可能丢失
    • 丢失最后一次快照以后的数据
      • 例如配置为每5分钟保存一次,在故障发生时可能丢失最近5分钟数据
      • 不适合对数据完整性要求高的场景(如金融交易系统)
    • 在服务器宕机等意外情况下数据丢失风险较大

AOF(Append Only File)持久化机制

AOF(Append Only File)是Redis提供的另一种持久化方式,与RDB方式不同,AOF通过记录所有写操作命令来实现数据持久化。在Redis默认配置中,AOF持久化是不开启的,需要手动启用。

工作原理

Redis会以追加写入的方式将所有对数据库执行的写入命令(如SET、LPUSH等)按照Redis协议格式记录到AOF文件中。当Redis重启时,会读取AOF文件并按顺序执行这些指令来重建数据状态。这种机制保证了数据的完整性,因为每个修改操作都被记录下来。

与RDB的区别

AOF 会记录过程,RDB 是保存结果。具体表现为:

  • RDB是定期生成数据快照,保存的是某个时间点的完整数据
  • AOF则记录所有的写操作命令,保存的是数据变更的历史记录
  • AOF文件通常比RDB文件大,但恢复更精确
  • RDB恢复速度更快,AOF恢复速度较慢但数据更完整

配置参数详解

要启用AOF持久化,需要修改Redis配置文件 redis.conf

# 开启AOF持久化(默认no)
appendonly yes

# 指定AOF文件保存位置(与RDB共用这个目录)
dir ./

# 设置AOF文件名(默认appendonly.aof)
appendfilename appendonly.aof

# AOF持久化策略(默认everysec)
# appendfsync always   # 每次写入都同步到磁盘,最安全但性能最差
# appendfsync everysec # 每秒同步一次,兼顾安全性和性能(推荐)
# appendfsync no       # 由操作系统决定何时同步,性能最好但安全性最差

# AOF重写相关配置
auto-aof-rewrite-percentage 100  # 当AOF文件大小增长超过上次重写后大小的100%时触发重写
auto-aof-rewrite-min-size 64mb   # 允许重写的最小AOF文件大小

使用建议

  1. 对于数据安全性要求高的场景,建议同时启用RDB和AOF
  2. 生产环境通常使用appendfsync everysec平衡性能和数据安全
  3. 定期监控AOF文件大小,必要时手动执行BGREWRITEAOF命令
  4. 可以通过redis-check-aof工具修复损坏的AOF文件

具体原理

AOF 文件中存储的 Redis 的指令,具体过程有三个阶段:

  • 命令传播:Redis 将执行完的命令、参数等发送到 AOF 程序中
  • 缓存追加:AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议格式,再追加到服务器的AOF缓存中。
  • 文件写入保存: AOF 缓存中的内容会被写入到 AOF 文件末尾,如果设定的AOF保存条件被满足的话,fsync函数或者fdatasync函数会被调用,写入的内容被真正的保存到磁盘中

保存方式

可以配置保存的方式如下:

  • AOF_FSYNC_NO 不保存
  • AOF_FSYNC_EVERYSEC 每一秒钟保存一次 (默认)
  • AOF_FSYNC_ALWAYS 每一个指令保存一次

在这里插入图片描述

AOF 瘦身

平常会遇到如下的场景

set name wzk
set name kangkang # 此时 保存 set name wzk 是没有意义的
set age 13

或者是这种场景

lpush list 1 2 3
lpush list 4 5 6
# 这种优化完可以变成: lpush 1 2 3 4 5 6

Redis 不希望 AOF 重写造成服务器无法处理请求,所以 Redis 决定将 AOF 重写程序放入到后台中:

  • 子进程AOF重写期间,主进程可以继续处理请求
  • 子进程带有主进程的发数据副本,使用子进程

不过使用子进程也有一个问题: 因为子进程在进行AOF重写期间,主进程还需要继续处理命令,而新的命令可能会对现有的数据进行修改,这会让当前数据库的数据和重写后的AOF文件中的数据不一致为了解决不一致的问题,Redis 加了一个 AOF 缓存,这个缓存在Fork出子进程之后,Redis主进程接收到新的写命令时,除了会将这个命令追加到现有的AOF文件,还会追加到这个缓存中。

具体的逻辑图如下: 在这里插入图片描述

触发方式

可以修改 redis.conf

# 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-percentage 100
# 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb

显式触发

bgrewriteaof

持久化混合模式详解

RDB 和 AOF 持久化对比

Redis 提供了两种主要的持久化方式,各有其优缺点:

RDB (Redis Database) 方式:

  • 优点:
    • 紧凑的二进制格式,文件体积小
    • 恢复速度快,适合大规模数据恢复
    • 对性能影响较小,因为采用子进程方式生成快照
  • 缺点:
    • 数据安全性较低,可能丢失最后一次快照后的数据
    • 大数据量时,fork操作可能阻塞主线程

AOF (Append Only File) 方式:

  • 优点:
    • 数据安全性高,最多丢失1秒的数据
    • 可读性强,以日志形式记录每个写操作
    • 支持后台重写,减少文件体积
  • 缺点:
    • 文件体积通常比RDB大
    • 恢复速度较慢
    • 对性能影响较大,特别是fsync策略设置为always时

混合持久化模式

从 Redis 4.0 版本开始,引入了 RDB+AOF 混合持久化模式,结合了两者的优势:

  1. 工作原理

    • AOF重写时,先将数据集以RDB格式写入AOF文件开头
    • 之后的新增命令继续以AOF格式追加
    • 这样生成的AOF文件包含两部分:RDB格式的全量数据和AOF格式的增量数据
  2. 优势

    • 兼具RDB的快速恢复和AOF的数据安全性
    • 与纯AOF相比,文件体积更小
    • 恢复速度比纯AOF快
  3. 配置方法: 在redis.conf配置文件中设置:

    aof-use-rdb-preamble yes
    
  4. 实际应用场景

    • 需要平衡数据安全性和恢复速度的业务
    • 适合数据量较大但又不希望恢复时间太长的场景
    • 可以替代单独使用RDB或AOF的方案
  5. 注意事项

    • 仅Redis 4.0及以上版本支持
    • 在Redis重启时,会优先识别并加载AOF文件中的RDB部分
    • 混合模式下的AOF文件可能比纯AOF更大,但比纯RDB+纯AOF的组合要小