第五章:持久化机制

深入了解 Redis 的持久化机制:RDB、AOF 以及混合持久化。

最后更新: 2024-01-15
页面目录

Redis 持久化机制

Redis 的持久化机制确保数据在服务器重启后不会丢失。本章详细介绍 RDB、AOF 和混合持久化三种方式。

持久化概述

┌─────────────────────────────────────────────────────────────────┐
│                     Redis 持久化方式                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌─────────────────┐     ┌─────────────────┐                  │
│   │      RDB       │     │      AOF         │                  │
│   │  (快照方式)     │     │  (日志方式)       │                  │
│   └────────┬────────┘     └────────┬────────┘                  │
│            │                       │                           │
│            └───────────┬───────────┘                           │
│                        ↓                                        │
│              ┌─────────────────┐                               │
│              │    混合持久化     │                              │
│              │   (Redis 4.0+)   │                              │
│              └─────────────────┘                               │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

RDB 持久化

RDB(Redis Database)通过创建数据快照的方式实现持久化。

工作原理

                        ┌─────────────────┐
                        │   Redis Server   │
                        └────────┬────────┘
                        ┌────────▼────────┐
                        │   fork() 进程   │
                        └────────┬────────┘
         ┌───────────────────────┼───────────────────────┐
         ↓                       ↓                       ↓
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   父进程继续     │     │   子进程写入     │     │   写入 dump.rdb  │
│   处理请求      │     │   内存快照       │     │                 │
└─────────────────┘     └─────────────────┘     └────────┬────────┘
                                                ┌─────────────────┐
                                                │   磁盘文件       │
                                                │   dump.rdb      │
                                                └─────────────────┘

触发方式

1. 自动触发

# redis.conf
save 900 1        # 900秒内至少1个key变化
save 300 10        # 300秒内至少10个key变化
save 60 10000      # 60秒内至少10000个key变化

2. 手动触发

# 同步保存(阻塞)
SAVE

# 异步保存(后台执行,推荐)
BGSAVE

配置参数

# RDB 文件名
dbfilename dump.rdb

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

# RDB 压缩
rdbcompression yes

# RDB 校验
rdbchecksum yes

# 失败停止写入
stop-writes-on-bgsave-error yes

优缺点

优点 缺点
文件紧凑,适合备份 可能丢失最后一次快照后的数据
恢复速度快 fork() 时占用内存
适合灾难恢复
适合全量备份

AOF 持久化

AOF(Append Only File)通过记录所有写操作命令实现持久化。

工作原理

┌─────────────────────────────────────────────────────────────────┐
│                        AOF 工作流程                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   Client → SET key value                                        │
│            │                                                    │
│            ↓                                                    │
│   ┌─────────────────┐                                           │
│   │   Redis Server  │                                           │
│   └────────┬────────┘                                           │
│            ↓                                                    │
│   ┌─────────────────┐     ┌─────────────────┐                  │
│   │   执行命令       │ ──► │   追加写入       │                  │
│   └─────────────────┘     │   appendonly.aof │                  │
│                           └─────────────────┘                   │
│                                                                  │
│   触发重写时:                                                   │
│   ┌─────────────────┐                                           │
│   │   bgrewriteaof  │                                           │
│   └────────┬────────┘                                           │
│            ↓                                                    │
│   ┌─────────────────┐                                           │
│   │   压缩文件       │                                           │
│   └─────────────────┘                                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

同步策略

# 同步策略
appendonly yes
appendfilename "appendonly.aof"

# 每次写入都同步(最安全,性能最差)
appendfsync always

# 每秒同步(推荐,性能和安全平衡)
appendfsync everysec

# 操作系统决定(性能最好,可能丢失数据)
appendfsync no

AOF 重写

# 自动重写触发条件
auto-aof-rewrite-percentage 100  # 文件比上次大100%时重写
auto-aof-rewrite-min-size 64mb   # 文件大于64MB时可能重写

# 忽略最后一条可能被截断的命令
aof-load-truncated yes

# 启用 RDB + AOF 混合持久化(Redis 7.0+)
aof-use-rdb-preamble yes

手动重写

# 手动触发 AOF 重写
BGREWRITEAOF

优缺点

优点 缺点
数据安全性更高 文件比 RDB 大
写入策略灵活 恢复速度较慢
尾部追加,效率高 可能出现截断问题

混合持久化

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

工作原理

┌─────────────────────────────────────────────────────────────────┐
│                     混合持久化原理                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   重写时:                                                       │
│   ┌─────────────────┐                                           │
│   │   生成 RDB 格式  │                                           │
│   │   的数据部分     │                                           │
│   └────────┬────────┘                                           │
│            │                                                    │
│            ↓                                                    │
│   ┌─────────────────┐                                           │
│   │   追加 AOF 格式  │                                          │
│   │   的增量命令     │                                           │
│   └────────┬────────┘                                           │
│            │                                                    │
│            ↓                                                    │
│   ┌─────────────────┐                                           │
│   │   混合文件       │                                          │
│   │   RDB + AOF     │                                          │
│   └─────────────────┘                                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

文件格式

┌─────────────────────────────────────────────────────────────────┐
│                     混合 AOF 文件格式                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │ REDIS (RDB 格式数据)                                      │   │
│   │ ┌────────┐ ┌────────┐ ┌────────┐                       │   │
│   │ │ Key 1  │ │ Key 2  │ │ Key 3  │  ← RDB 二进制格式       │   │
│   │ └────────┘ └────────┘ └────────┘                       │   │
│   └─────────────────────────────────────────────────────────┘   │
│   │                                                         │   │
│   │ *3\r\n$3\r\nSET\r\n...                                  │   │
│   │ *3\r\n$3\r\nSET\r\n...                                  │   │
│   │                         ↑ 纯文本 AOF 增量命令              │   │
│   └─────────────────────────────────────────────────────────┘   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

配置启用

# 启用混合持久化(Redis 7.0 默认开启)
aof-use-rdb-preamble yes

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

持久化配置推荐

缓存模式(仅 RDB)

# 适合对数据丢失容忍度较高的场景
save 900 1
save 300 10
save 60 10000

dbfilename dump.rdb
dir /var/lib/redis
rdbcompression yes
rdbchecksum yes

生产环境(混合持久化)

# 适合生产环境,推荐配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

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

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

# RDB 快照
save 900 1
save 300 10
save 60 10000

高性能模式(AOF everysec)

# 追求高性能,适度持久化
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes

数据恢复

从 RDB 恢复

# 1. 确保 Redis 已停止
sudo systemctl stop redis

# 2. 备份当前数据
mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak

# 3. 恢复文件
cp /path/to/backup/dump.rdb /var/lib/redis/

# 4. 设置权限
chown redis:redis /var/lib/redis/dump.rdb

# 5. 启动 Redis
sudo systemctl start redis

从 AOF 恢复

# 1. 检查 AOF 文件
redis-check-aof --fix /var/lib/redis/appendonly.aof

# 2. 重启 Redis
sudo systemctl restart redis

从混合持久化恢复

# 自动识别格式并恢复
redis-server /etc/redis/redis.conf
redis-cli

# 验证数据
KEYS *

备份策略

定时备份脚本

#!/bin/bash
# redis-backup.sh

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

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

# 触发 BGSAVE
redis-cli BGSAVE

# 等待保存完成
while [ $(redis-cli LASTSAVE) == $(redis-cli -c LASTSAVE) ]; do
    sleep 1
done

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

# 复制 AOF 文件(如果启用)
if [ -f /var/lib/redis/appendonly.aof ]; then
    cp /var/lib/redis/appendonly.aof ${BACKUP_DIR}/appendonly_${DATE}.aof
fi

# 创建压缩包
cd ${BACKUP_DIR}
tar czf redis_backup_${DATE}.tar.gz dump_${DATE}.rdb
[ -f appendonly_${DATE}.aof ] && tar czf redis_backup_${DATE}.tar.gz dump_${DATE}.rdb appendonly_${DATE}.aof

# 清理临时文件
rm -f dump_${DATE}.rdb appendonly_${DATE}.aof

# 上传到远程存储
# aws s3 cp redis_backup_${DATE}.tar.gz s3://my-bucket/redis/

# 清理旧备份
find ${BACKUP_DIR} -name "redis_backup_*.tar.gz" -mtime +${KEEP_DAYS} -delete

echo "备份完成: redis_backup_${DATE}.tar.gz"

Crontab 配置

# 每天凌晨 2 点备份
0 2 * * * /opt/scripts/redis-backup.sh >> /var/log/redis-backup.log 2>&1

性能影响

持久化方式 fork() I/O 操作 内存占用
RDB 一次性 2倍
AOF everysec 每秒 追加
混合持久化 一次性+追加 适中

下一步

接下来让我们学习 Redis 的主从复制。

👉 主从复制