Redis红宝书 Redis 持久化机制

114 阅读7分钟

Redis 持久化机制

概述

Redis 是一个内存数据库,为了保证数据的持久性,Redis 提供了两种主要的持久化方式:RDB(Redis Database)和 AOF(Append Only File)。从 Redis 7.0 开始,还引入了混合持久化模式,结合了两种方式的优点。

RDB 持久化

原理

RDB 持久化是通过创建数据集的时间点快照(snapshot)来实现的。Redis 会在指定的时间间隔内,将内存中的数据集快照写入磁盘,生成一个二进制文件(通常命名为 dump.rdb)。

工作流程:

  1. Redis 主进程 fork 出一个子进程
  2. 子进程将内存中的数据写入临时 RDB 文件
  3. 写入完成后,用临时文件替换旧的 RDB 文件
  4. 子进程退出

触发条件

  • 自动触发: 根据配置的 save 规则
  • 手动触发: 执行 SAVE 或 BGSAVE 命令
  • 其他触发: 主从复制、SHUTDOWN 命令等

配置示例

# 在 900 秒内至少有 1 个键被修改时保存
save 900 1
# 在 300 秒内至少有 10 个键被修改时保存
save 300 10
# 在 60 秒内至少有 10000 个键被修改时保存
save 60 10000

# RDB 文件名
dbfilename dump.rdb

# RDB 文件保存目录
dir /var/lib/redis

优点

  1. 紧凑性: RDB 文件是一个紧凑的二进制文件,占用空间小
  2. 恢复速度快: 相比 AOF,RDB 文件恢复数据速度更快
  3. 适合备份: 单个文件便于备份和传输
  4. 性能影响小: 主进程不参与 I/O 操作,对性能影响较小

缺点

  1. 数据丢失风险: 在两次快照之间的数据可能丢失
  2. fork 开销: 数据量大时,fork 子进程可能耗时较长
  3. 不适合实时性要求高的场景

AOF 持久化

原理

AOF(Append Only File)持久化通过记录服务器执行的所有写操作命令来实现。Redis 会将每个写命令追加到 AOF 文件的末尾,重启时通过重新执行这些命令来恢复数据。

工作流程:

  1. 客户端发送写命令
  2. Redis 执行命令并将结果存储到内存
  3. 将命令追加到 AOF 缓冲区
  4. 根据同步策略将缓冲区内容写入 AOF 文件

同步策略

# 每次写操作都同步到磁盘(最安全,性能最差)
appendfsync always

# 每秒同步一次(默认,平衡安全性和性能)
appendfsync everysec

# 由操作系统决定何时同步(性能最好,安全性最差)
appendfsync no

AOF 重写

随着时间推移,AOF 文件会越来越大。Redis 提供 AOF 重写机制来压缩文件大小:

# 启用 AOF
appendonly yes

# AOF 文件名
appendfilename "appendonly.aof"

# 自动重写条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

优点

  1. 数据安全性高: 根据同步策略,最多丢失 1 秒的数据
  2. 文件可读: AOF 文件是文本格式,便于理解和修复
  3. 增量备份: 支持增量备份
  4. 自动修复: 提供 redis-check-aof 工具修复损坏的文件

缺点

  1. 文件体积大: 相同数据集,AOF 文件通常比 RDB 文件大
  2. 恢复速度慢: 需要重新执行所有命令
  3. 性能开销: 每次写操作都需要记录日志

Redis 7.0 混合持久化模式

概述

Redis 7.0 引入了混合持久化模式,结合了 RDB 和 AOF 的优点。在 AOF 重写时,Redis 会将当前内存中的数据以 RDB 格式写入 AOF 文件的开头,然后将重写期间的增量命令以 AOF 格式追加到文件末尾。

配置

# 启用混合持久化(Redis 4.0+ 支持,7.0 优化)
aof-use-rdb-preamble yes

# 同时启用 RDB 和 AOF
save 900 1
appendonly yes
appendfsync everysec

文件目录结构

/var/lib/redis/
├── dump.rdb                 # RDB 快照文件
├── appendonly.aof           # AOF 日志文件(混合格式)
├── appendonly.aof.1.base.rdb # AOF 重写时的 RDB 基础文件
├── appendonly.aof.1.incr.aof # AOF 重写时的增量文件
└── appendonly.aof.manifest   # AOF 文件清单

Redis 7.0 多部分 AOF

Redis 7.0 引入了多部分 AOF 架构:

  • Base AOF: 包含重写时的完整数据快照(RDB 格式)
  • Incremental AOF: 包含重写后的增量命令
  • Manifest 文件: 记录 AOF 文件的元信息

工作原理

  1. 正常运行: 写命令同时记录到 AOF 文件
  2. 触发重写: 创建新的 Base AOF(RDB 格式)+ Incremental AOF
  3. 重写完成: 更新 Manifest 文件,切换到新的 AOF 文件组
  4. 数据恢复: 先加载 Base AOF,再重放 Incremental AOF

优势

  1. 快速恢复: Base AOF 采用 RDB 格式,加载速度快
  2. 数据安全: 保持 AOF 的数据安全特性
  3. 文件管理: 多文件架构便于管理和维护
  4. 减少重写开销: 重写过程更加高效

混合持久化是否还需要RDB?

答案:通常不需要单独的RDB

在混合持久化模式下,AOF重写时会生成RDB格式的Base文件,这已经包含了完整的数据快照。因此:

  1. 冗余性考虑: 单独的RDB文件与Base AOF功能重复
  2. 存储优化: 避免重复存储相同数据
  3. 维护简化: 减少文件管理复杂度

例外情况:

  • 备份需求: 如果需要定期的独立备份文件
  • 兼容性: 某些监控工具依赖RDB文件
  • 迁移场景: 数据迁移时RDB文件更便于传输

混合持久化详细流程

流程图
flowchart TD
    A[Redis启动] --> B[加载现有数据]
    B --> C{检查文件类型}
    C -->|有Manifest文件| D[多部分AOF模式]
    C -->|只有AOF文件| E[传统AOF模式]
    C -->|只有RDB文件| F[RDB模式]
    
    D --> G[读取Manifest]
    G --> H[加载Base AOF]
    H --> I[加载Incremental AOF]
    I --> J[数据恢复完成]
    
    J --> K[正常运行]
    K --> L[写命令执行]
    L --> M[记录到当前AOF]
    M --> N{触发重写条件?}
    N -->|否| L
    N -->|是| O[开始AOF重写]
    
    O --> P[Fork子进程]
    P --> Q[子进程生成新Base AOF<br/>RDB格式]
    P --> R[主进程继续服务<br/>记录到Incremental AOF]
    
    Q --> S[Base AOF生成完成]
    R --> T[Incremental AOF记录]
    S --> U[更新Manifest文件]
    T --> U
    U --> V[切换到新AOF文件组]
    V --> W[清理旧文件]
    W --> K
详细步骤说明

1. 启动阶段

# 数据恢复优先级
1. 检查appendonly.aof.manifest文件
2. 如果存在,按Manifest加载多部分AOF
3. 如果不存在,检查appendonly.aof
4. 最后检查dump.rdb

2. 正常运行阶段

# 写操作流程
Client --> Redis Server --> Memory Update --> AOF Buffer --> Disk Sync
                        \--> Replication Buffer (if slaves exist)

3. AOF重写触发

# 自动触发条件
- AOF文件大小超过auto-aof-rewrite-min-size
- AOF文件增长比例超过auto-aof-rewrite-percentage

# 手动触发
BGREWRITEAOF

4. 混合重写过程

# 步骤详解
1. 主进程fork子进程
2. 子进程开始生成新的Base AOF(RDB格式)
3. 主进程继续处理客户端请求
4. 重写期间的新命令记录到Incremental AOF
5. 子进程完成Base AOF生成
6. 主进程更新Manifest文件
7. 原子性切换到新的AOF文件组
8. 清理旧的AOF文件

5. 文件结构变化

# 重写前
/var/lib/redis/
├── appendonly.aof.1.base.rdb
├── appendonly.aof.1.incr.aof
└── appendonly.aof.manifest

# 重写中
/var/lib/redis/
├── appendonly.aof.1.base.rdb     # 旧文件
├── appendonly.aof.1.incr.aof     # 旧文件
├── appendonly.aof.2.base.rdb     # 新生成
├── appendonly.aof.2.incr.aof     # 新增量
└── appendonly.aof.manifest       # 更新中

# 重写后
/var/lib/redis/
├── appendonly.aof.2.base.rdb     # 新基础文件
├── appendonly.aof.2.incr.aof     # 新增量文件
└── appendonly.aof.manifest       # 已更新

配置示例

推荐的混合持久化配置
# redis.conf 混合持久化最佳配置

# 禁用RDB(混合模式下不需要)
# save ""  # 注释掉所有save配置
# 或者设置为空
save ""

# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# 混合持久化(关键配置)
aof-use-rdb-preamble yes

# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 数据目录
dir /var/lib/redis

# 可选:如果需要独立RDB备份
# save 3600 1  # 每小时至少1个变更时备份
兼容性配置(保留RDB)
# 如果需要同时保留RDB(用于备份或兼容性)

# RDB 配置(降低频率)
save 3600 1      # 每小时备份一次
save 86400 100   # 每天备份一次(如果有100个变更)
dbfilename dump.rdb

# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

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

# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 数据目录
dir /var/lib/redis

持久化策略选择

场景建议

  1. 高可用性要求: 使用 AOF + 混合持久化
  2. 性能优先: 使用 RDB
  3. 平衡方案: 使用混合持久化模式
  4. 备份需求: RDB + AOF 双重保障

监控和维护

# 查看持久化状态
INFO persistence

# 手动触发 RDB 保存
BGSAVE

# 手动触发 AOF 重写
BGREWRITEAOF

# 检查 AOF 文件
redis-check-aof --fix appendonly.aof

总结

Redis 7.0 的混合持久化模式通过结合 RDB 的快速恢复和 AOF 的数据安全特性,为用户提供了更好的持久化解决方案。多部分 AOF 架构进一步优化了文件管理和重写性能,是现代 Redis 部署的推荐配置。