跳到主要内容

Redis 持久化

持久化是将内存中的数据保存到磁盘的过程。Redis 提供了 RDB 和 AOF 两种持久化方式,本章将详细介绍这两种方式的原理和配置。

持久化概述

┌─────────────────────────────────────────────────────────────┐
│ Redis 持久化方式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Redis 内存数据 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ RDB 快照 │ │ AOF 日志 │ │
│ │ 二进制文件 │ │ 文本文件 │ │
│ │ 定时保存 │ │ 追加写入 │ │
│ │ 恢复速度快 │ │ 数据更安全 │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

RDB 持久化

RDB(Redis Database)是将某一时刻的内存数据保存到磁盘的二进制文件(默认为 dump.rdb)。

RDB 工作原理

┌─────────────────────────────────────────────────────────────┐
│ RDB 快照流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 客户端触发 BGSAVE 命令 │
│ │ │
│ 2. Redis 主进程 fork 子进程 │
│ │ │
│ 3. 子进程将内存数据写入临时 RDB 文件 │
│ │ │
│ 4. 子进程完成,替换旧的 RDB 文件 │
│ │ │
│ 5. 主进程继续处理客户端请求 │
│ │
│ 注意:fork 使用写时复制(Copy-on-Write)技术 │
│ │
└─────────────────────────────────────────────────────────────┘

RDB 配置

# redis.conf 配置

# 触发快照的条件
# save <秒> <变化次数>
save 900 1 # 900 秒内有 1 次变化
save 300 10 # 300 秒内有 10 次变化
save 60 10000 # 60 秒内有 10000 次变化

# 禁用 RDB(注释掉所有 save 或设置空字符串)
# save ""

# RDB 文件名
dbfilename dump.rdb

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

# 压缩(默认开启)
rdbcompression yes

# 校验和(默认开启)
rdbchecksum yes

# RDB 文件存储失败时是否停止写入
stop-writes-on-bgsave-error yes

RDB 命令

# 手动触发快照(后台执行)
BGSAVE

# 手动触发快照(前台执行,会阻塞)
SAVE

# 获取上次保存时间
LASTSAVE

# 查看持久化状态
INFO persistence

RDB 优缺点

优点

  • 文件紧凑,适合备份
  • 恢复速度快
  • 对性能影响小(子进程执行)
  • 适合灾难恢复

缺点

  • 数据安全性较低(可能丢失几分钟数据)
  • fork 大数据集时可能阻塞

AOF 持久化

AOF(Append Only File)记录所有写操作命令,恢复时重新执行这些命令。

AOF 工作原理

### AOF 工作流程 (Redis 7.0+)

从 Redis 7.0 开始,AOF 架构演进为 **Multi-Part AOF**,大大降低了重写(Rewrite)的开销:

- **Base AOF**:主要的 AOF 文件,代表了开始重写时刻的数据快照。
- **Incremental AOF**:在重写过程中产生的增量日志。
- **Manifest File**:追踪并管理这些 AOF 文件。

**优势**:不再需要由于重写导致的大量内存写时复制(COW)开销,数据持久化更加平稳且高效。

AOF 配置

# redis.conf 配置

# 启用 AOF
appendonly yes

# AOF 文件名
appendfilename "appendonly.aof"

# AOF 目录(Redis 7.0+)
appenddirname "appendonlydir"

# 同步策略
# always : 每次写入都同步,最安全但最慢
# everysec : 每秒同步一次(推荐)
# no : 由操作系统决定,最快但不安全
appendfsync everysec

# 重写期间是否禁用 fsync
no-appendfsync-on-rewrite no

# AOF 重写触发条件
auto-aof-rewrite-percentage 100 # 文件比上次重写后增长 100%
auto-aof-rewrite-min-size 64mb # 文件最小 64MB

# 加载损坏的 AOF 文件是否继续
aof-load-truncated yes

# 使用 RDB-AOF 混合格式(Redis 4.0+)
aof-use-rdb-preamble yes

AOF 重写

AOF 文件会随着写操作不断增长,重写可以压缩文件大小:

# 手动触发重写
BGREWRITEAOF

# 查看重写状态
INFO persistence

重写原理

  1. fork 子进程
  2. 子进程将当前内存数据写入临时文件
  3. 主进程继续记录新写入到重写缓冲区
  4. 子进程完成后,主进程追加重写缓冲区
  5. 替换旧 AOF 文件

AOF 优缺点

优点

  • 数据更安全(最多丢失 1 秒数据)
  • AOF 文件可读,便于分析
  • 文件损坏可修复

缺点

  • 文件体积较大
  • 恢复速度较慢
  • 对性能有影响

RDB 与 AOF 对比

特性RDBAOF
数据安全性较低(分钟级丢失)较高(秒级丢失)
文件大小
恢复速度
系统资源消耗低(fork 时)较高(持续写入)
文件可读性二进制文本
适用场景备份、主从复制数据安全要求高

混合持久化

Redis 4.0 引入混合持久化,结合 RDB 和 AOF 的优点:

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

工作原理

  • AOF 重写时,先写入 RDB 格式的快照
  • 然后追加增量的 AOF 命令
  • 恢复时先加载 RDB 部分,再执行 AOF 命令

持久化配置建议

场景一:纯缓存(可接受数据丢失)

# 关闭持久化
save ""
appendonly no

场景二:数据安全要求高

# 开启 AOF
appendonly yes
appendfsync everysec

# 也保留 RDB 用于备份
save 900 1
save 300 10

场景三:平衡方案

# 开启 AOF 和混合持久化
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes

# RDB 用于快速重启和备份
save 900 1
save 300 10
save 60 10000

数据恢复

RDB 恢复

# 1. 停止 Redis
redis-cli shutdown

# 2. 将 dump.rdb 复制到数据目录
cp /backup/dump.rdb /var/lib/redis/

# 3. 启动 Redis
redis-server /etc/redis/redis.conf

AOF 恢复

# 1. 停止 Redis
redis-cli shutdown

# 2. 复制 AOF 文件
cp /backup/appendonly.aof /var/lib/redis/

# 3. 修复损坏的 AOF(如需要)
redis-check-aof --fix appendonly.aof

# 4. 启动 Redis
redis-server /etc/redis/redis.conf

从 RDB 切换到 AOF

# 在线切换(Redis 2.2+)
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET save ""

# 持久化配置
redis-cli CONFIG REWRITE

备份策略

#!/bin/bash
# Redis 备份脚本

BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份目录
mkdir -p $BACKUP_DIR

# 触发 RDB 快照
redis-cli BGSAVE

# 等待快照完成
sleep 5

# 复制 RDB 文件
cp /var/lib/redis/dump.rdb $BACKUP_DIR/dump_$DATE.rdb

# 压缩
gzip $BACKUP_DIR/dump_$DATE.rdb

# 删除 7 天前的备份
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete

echo "Backup completed: dump_$DATE.rdb.gz"

小结

本章我们学习了:

  1. RDB 持久化:快照方式,恢复快但可能丢数据
  2. AOF 持久化:日志方式,数据安全但文件大
  3. 混合持久化:结合两者优点
  4. 配置建议:根据场景选择合适策略
  5. 数据恢复:RDB 和 AOF 的恢复方法

练习

  1. 配置 RDB 持久化并手动触发快照
  2. 配置 AOF 持久化并观察文件变化
  3. 模拟 Redis 重启并恢复数据
  4. 编写自动备份脚本

参考资源