# Redis 持久化机制详解

# 概述

Redis 是一个内存数据库,数据存储在内存中。如果服务器进程退出,服务器中的数据也会丢失。为了解决这个问题,Redis 提供了两种持久化机制:

  • RDB(Redis Database):定时快照方式
  • AOF(Append Only File):日志追加方式

本文将详细介绍这两种持久化机制的原理、配置和使用场景。

# RDB 持久化

# 什么是 RDB

RDB 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。它生成的文件是一个经过压缩的二进制文件,Redis 可以通过这个文件来恢复数据。

# RDB 工作原理

1
2
3
4
5
graph TD
A[Redis服务器] --> B[fork子进程]
B --> C[子进程写入临时文件]
C --> D[原子性替换RDB文件]
D --> E[删除临时文件]

# RDB 配置

在 redis.conf 中配置 RDB:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 启用RDB持久化
save 900 1 # 900秒内至少有1个key被改变
save 300 10 # 300秒内至少有10个key被改变
save 60 10000 # 60秒内至少有10000个key被改变

# RDB文件名
dbfilename dump.rdb

# RDB文件存储路径
dir /opt/homebrew/var/db/redis/

# 是否启用压缩
rdbcompression yes

# RDB文件是否校验
rdbchecksum yes

# 后台保存出错时是否停止写入
stop-writes-on-bgsave-error yes

# RDB 触发方式

# 1. 自动触发

根据配置的 save 条件自动触发

# 2. 手动触发

1
2
3
4
5
# 同步保存,会阻塞主进程
SAVE

# 异步保存,不会阻塞主进程
BGSAVE

# 3. 其他触发

  • 执行 FLUSHALL 命令
  • 执行 SHUTDOWN 命令
  • 主从复制中的从节点

# RDB 优缺点

# 优点

  • 文件紧凑:RDB 文件是压缩的二进制文件,体积小
  • 恢复速度快:直接加载 RDB 文件即可恢复数据
  • 对性能影响小:使用子进程进行持久化,不影响主进程

# 缺点

  • 数据安全性低:在两次快照之间如果服务器宕机,会丢失数据
  • fork 过程耗时:在数据量大的情况下,fork 子进程会比较耗时

# AOF 持久化

# 什么是 AOF

AOF 持久化以日志的形式记录服务器处理的每一个写操作命令,当服务器重启时,会重新执行这些命令来恢复数据。

# AOF 工作原理

1
2
3
4
graph TD
A[客户端写命令] --> B[写入AOF缓冲区]
B --> C[同步到AOF文件]
C --> D[文件重写优化]

# AOF 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 启用AOF持久化
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# AOF文件存储路径
dir /opt/homebrew/var/db/redis/

# AOF同步策略
# always: 每个写命令都同步,最安全但最慢
# everysec: 每秒同步一次,折中方案
# no: 由操作系统决定何时同步,最快但不安全
appendfsync everysec

# AOF重写触发条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# AOF文件是否包含最后一条可能不完整的命令
aof-load-truncated yes

# AOF 同步策略详解

# always(总是同步)

1
appendfsync always

  • 每个写命令都立即同步到磁盘
  • 数据安全性最高,但性能最差
  • 适用于对数据安全性要求极高的场景

# everysec(每秒同步)

1
appendfsync everysec

  • 每秒同步一次,默认推荐配置
  • 在性能和数据安全性之间取得平衡
  • 最多丢失 1 秒的数据

# no(不同步)

1
appendfsync no

  • 由操作系统决定何时同步
  • 性能最好,但数据安全性最低
  • 适用于对数据安全性要求不高的场景

# AOF 重写

# 为什么需要 AOF 重写

随着时间推移,AOF 文件会越来越大,包含很多冗余命令。AOF 重写可以创建一个新的、紧凑的 AOF 文件。

# AOF 重写原理

1
2
3
4
5
graph TD
A[当前数据库状态] --> B[生成新的AOF命令]
B --> C[写入临时文件]
C --> D[原子性替换原AOF文件]
D --> E[删除临时文件]

# 手动触发 AOF 重写

1
BGREWRITEAOF

# 自动触发条件

1
2
3
4
5
# AOF文件增长超过100%时触发重写
auto-aof-rewrite-percentage 100

# AOF文件最小达到64MB时才触发重写
auto-aof-rewrite-min-size 64mb

# AOF 优缺点

# 优点

  • 数据安全性高:可以配置为每个命令都同步
  • 数据完整性:记录所有写操作,数据丢失风险低
  • 可读性强:AOF 文件是文本格式,可读性好

# 缺点

  • 文件体积大:记录所有写操作,文件比 RDB 大
  • 恢复速度慢:需要重新执行所有命令
  • 性能影响:频繁的磁盘 I/O 操作影响性能

# 混合持久化

# 什么是混合持久化

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

  • AOF 文件前半部分是 RDB 格式的数据
  • AOF 文件后半部分是增量 AOF 格式的命令

# 混合持久化配置

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

# 混合持久化优势

  • 快速恢复:先加载 RDB 部分,再执行增量命令
  • 文件体积小:RDB 部分压缩了数据
  • 数据安全:AOF 部分保证了数据完整性

# 持久化选择策略

# 选择 RDB 的场景

  1. 数据备份:适合用于数据备份和灾难恢复
  2. 快速恢复:需要快速恢复大量数据的场景
  3. 内存充足:服务器内存较大,可以承受 fork 操作

# 选择 AOF 的场景

  1. 高数据安全性:对数据安全性要求极高的场景
  2. 数据完整性:不能容忍任何数据丢失的场景
  3. 写入频率低:写操作不频繁的场景

# 混合使用场景

  1. 生产环境:推荐使用混合持久化
  2. 数据量大:既需要快速恢复又需要数据安全的场景
  3. 综合需求:对性能和安全性都有要求的场景

# 持久化监控和维护

# 查看持久化状态

1
2
3
4
5
# 查看最后一次RDB保存的时间
LASTSAVE

# 查看AOF文件状态
INFO persistence

# 持久化文件管理

1
2
3
4
5
6
7
8
9
10
11
# 查看RDB文件大小
ls -lh /opt/homebrew/var/db/redis/dump.rdb

# 查看AOF文件大小
ls -lh /opt/homebrew/var/db/redis/appendonly.aof

# 检查AOF文件完整性
redis-check-aof /opt/homebrew/var/db/redis/appendonly.aof

# 修复AOF文件
redis-check-aof --fix /opt/homebrew/var/db/redis/appendonly.aof

# 持久化性能优化

# 1. 合理配置 save 条件

1
2
3
4
# 根据业务特点调整save条件
save 900 1 # 低频写入场景
save 300 10 # 中频写入场景
save 60 10000 # 高频写入场景

# 2. 优化 AOF 同步策略

1
2
# 根据数据安全性要求选择同步策略
appendfsync everysec # 推荐配置

# 3. 监控持久化性能

1
2
# 查看持久化相关指标
INFO persistence | grep -E "(rdb|aof)"

# 实战案例

# 案例 1:电商网站持久化配置

1
2
3
4
5
6
7
8
9
10
11
# 电商网站配置示例
save 900 1
save 300 100
save 60 10000

appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 1024mb

# 案例 2:日志系统持久化配置

1
2
3
4
5
6
7
8
# 日志系统配置示例
save 900 1
save 300 10
save 60 1000

appendonly yes
appendfsync always
aof-use-rdb-preamble no

# 案例 3:缓存系统持久化配置

1
2
3
4
5
6
7
8
# 缓存系统配置示例
save 900 1
save 300 10
save 60 100

appendonly yes
appendfsync no
aof-use-rdb-preamble yes

# 故障恢复

# RDB 恢复流程

  1. 停止 Redis 服务

    1
    brew services stop redis

  2. 备份 RDB 文件

    1
    cp /opt/homebrew/var/db/redis/dump.rdb /opt/homebrew/var/db/redis/dump.rdb.backup

  3. 恢复 RDB 文件

    1
    cp /path/to/backup/dump.rdb /opt/homebrew/var/db/redis/dump.rdb

  4. 启动 Redis 服务

    1
    brew services start redis

# AOF 恢复流程

  1. 停止 Redis 服务

    1
    brew services stop redis

  2. 检查 AOF 文件

    1
    redis-check-aof /opt/homebrew/var/db/redis/appendonly.aof

  3. 修复 AOF 文件(如果需要)

    1
    redis-check-aof --fix /opt/homebrew/var/db/redis/appendonly.aof

  4. 启动 Redis 服务

    1
    brew services start redis

# 最佳实践

# 1. 定期备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# 定期备份脚本
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/redis"

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

# 备份RDB文件
cp /opt/homebrew/var/db/redis/dump.rdb $BACKUP_DIR/dump_$DATE.rdb

# 备份AOF文件
cp /opt/homebrew/var/db/redis/appendonly.aof $BACKUP_DIR/appendonly_$DATE.aof

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

# 2. 监控脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
# 持久化监控脚本
REDIS_CLI="redis-cli"

# 检查RDB最后保存时间
LASTSAVE=$($REDIS_CLI LASTSAVE)
CURRENT_TIME=$(date +%s)
DIFF=$((CURRENT_TIME - LASTSAVE))

if [ $DIFF -gt 3600 ]; then
echo "警告:RDB文件超过1小时未更新"
fi

# 检查AOF文件大小
AOF_SIZE=$(stat -f%z /opt/homebrew/var/db/redis/appendonly.aof)
if [ $AOF_SIZE -gt 1073741824 ]; then
echo "警告:AOF文件超过1GB,建议执行重写"
fi

# 3. 配置优化建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 生产环境推荐配置
save 900 1
save 300 10
save 60 10000

appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 512mb

rdbcompression yes
rdbchecksum yes

stop-writes-on-bgsave-error yes

# 总结

Redis 持久化机制是保证数据安全的重要手段:

  • RDB:适合快速恢复和数据备份
  • AOF:适合高数据安全性和完整性要求
  • 混合持久化:结合两者优点,推荐在生产环境使用

根据业务需求选择合适的持久化策略,并做好监控和维护,才能确保 Redis 数据的安全性和可靠性。