Redis AOF 持久化详解
AOF(Append Only File)是 Redis 的日志式持久化机制,通过记录每个写操作实现数据持久化。本文将深入 AOF 的原理、配置和优化。
一、AOF 基础概念
1.1 什么是 AOF
AOF 是操作日志:
- 记录每个写操作
- 追加写入,顺序 IO
- 数据更安全
写操作 AOF 文件
┌─────────┐ ┌─────────────┐
│ SET k1 │ 追加 │ appendonly │
│ INCR k2 │ ──────▶ │ .aof │
│ DEL k3 │ │ (日志) │
└─────────┘ └─────────────┘
1.2 AOF 文件结构
AOF 文件格式:
┌─────────────────────────┐
│ *2 │ ← Redis 协议
│ $6 │
│ SELECT │
│ $1 │
│ 0 │
├─────────────────────────┤
│ *3 │
│ $3 │
│ SET │
│ $4 │
│ key1 │
│ $5 │
│ value │
├─────────────────────────┤
│ *3 │
│ $4 │
│ INCR │
│ $4 │
│ key2 │
│ ... │
└─────────────────────────┘
二、工作原理
2.1 命令追加
// 写命令处理
void feedAppendOnlyFile(client *c) {
// 1. 将命令转换为 Redis 协议
sds cmd = catAppendOnlyCmd(c);
// 2. 追加到 AOF 缓冲区
if (server.aof_state != AOF_OFF) {
server.aof_buf = sdscatlen(server.aof_buf, cmd, sdslen(cmd));
}
// 3. 根据策略刷盘
if (server.aof_flush_strategy == AOF_FLUSH_ALWAYS) {
flushAppendOnlyFile(0);
}
}
2.2 刷盘策略
# appendfsync 配置
appendfsync always # 每次写入都同步
appendfsync everysec # 每秒同步(默认)
appendfsync no # 由 OS 决定
对比:
| 策略 | 安全性 | 性能 | 推荐场景 |
|---|---|---|---|
always | 不丢失 | 低 | 金融 |
everysec | 丢 1 秒 | 中 | 一般(推荐) |
no | 丢多秒 | 高 | 缓存 |
2.3 刷盘流程
写命令
↓
追加到 AOF 缓冲区
↓
根据策略刷盘
├─ always: 立即 fsync
├─ everysec: 每秒 fsync
└─ no: OS 决定
↓
写入磁盘
三、配置详解
3.1 基本配置
# 启用 AOF
appendonly yes
# AOF 文件名
appendfilename "appendonly.aof"
# 工作目录
dir /var/lib/redis
3.2 同步策略
# 同步频率
appendfsync everysec
# 重写时是否同步
no-appendfsync-on-rewrite no
# AOF 重写触发
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
3.3 重写配置
# AOF 增长 100% 触发重写
auto-aof-rewrite-percentage 100
# AOF 最小 64MB 才重写
auto-aof-rewrite-min-size 64mb
# 禁用自动重写
auto-aof-rewrite-percentage 0
四、AOF 重写
4.1 为什么需要重写
问题:
AOF 文件只增不减
删除操作也记录
导致文件过大
示例:
INCR counter # +1
INCR counter # +1
INCR counter # +1
DEL counter # 删除
SET counter 5 # 设置
重写后:
SET counter 5 # 只保留最终状态
4.2 重写流程
BGREWRITEAOF
↓
fork 子进程
↓
子进程:
1. 读取当前数据
2. 写入新 AOF 文件
3. 最小化命令
父进程:
1. 继续服务
2. 写入命令到缓冲区
3. 重写完成后合并缓冲区
↓
重命名 AOF 文件
4.3 手动重写
# 触发重写
BGREWRITEAOF
# 检查状态
INFO persistence
# aof_rewrite_in_progress:0
# aof_last_rewrite_time_sec:10
4.4 混合持久化(Redis 4.0+)
# 启用混合持久化
aof-use-rdb-preamble yes
优势:
前缀:RDB 格式(紧凑)
后缀:AOF 增量(安全)
加载:
1. 快速加载 RDB 部分
2. 回放 AOF 增量
五、数据恢复
5.1 启动恢复
Redis 启动
↓
检查 AOF 文件
↓
加载 AOF 文件
↓
重放写命令
↓
恢复数据
5.2 恢复优先级
同时有 RDB 和 AOF:
1. 优先加载 AOF(数据更全)
2. AOF 不存在则加载 RDB
5.3 手动恢复
# 1. 停止 Redis
redis-cli SHUTDOWN
# 2. 备份当前 AOF
cp /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak
# 3. 替换 AOF 文件
cp backup/appendonly.aof /var/lib/redis/
# 4. 启动 Redis
redis-server /etc/redis/redis.conf
5.4 修复损坏的 AOF
# 检查 AOF 文件
redis-check-aof --fix /var/lib/redis/appendonly.aof
# 输出示例
Found inconsistent AOF file
Fixing AOF file...
AOF file fixed successfully
六、性能优化
6.1 刷盘优化
# 高性能场景
appendfsync no
no-appendfsync-on-rewrite yes
# 平衡场景(推荐)
appendfsync everysec
no-appendfsync-on-rewrite no
# 高安全场景
appendfsync always
6.2 重写优化
# 避免频繁重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 128mb
# 重写时不刷盘
no-appendfsync-on-rewrite yes
6.3 磁盘优化
# 使用 SSD
dir /mnt/ssd/redis
# 挂载选项
mount -o noatime,nodiratime /dev/sda1 /mnt/ssd
# 关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
七、监控与维护
7.1 监控指标
# 查看 AOF 状态
INFO persistence
# 输出示例
# Persistence
# aof_enabled:1
# aof_rewrite_in_progress:0
# aof_last_rewrite_time_sec:10
# aof_current_size:1048576
# aof_base_size:524288
7.2 日志分析
# 查看 AOF 大小
ls -lh /var/lib/redis/appendonly.aof
# 统计命令数量
grep -c "^\*" /var/lib/redis/appendonly.aof
# 查看最后写入时间
tail /var/lib/redis/appendonly.aof
7.3 定期维护
#!/bin/bash
# aof_maintenance.sh
REDIS_CLI="redis-cli"
AOF_FILE="/var/lib/redis/appendonly.aof"
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
# 触发重写
$REDIS_CLI BGREWRITEAOF
# 等待完成
while [ "$($REDIS_CLI INFO persistence | grep aof_rewrite_in_progress | cut -d: -f2)" == "1" ]; do
sleep 1
done
# 备份 AOF
cp $AOF_FILE $BACKUP_DIR/appendonly_$DATE.aof
# 压缩
gzip $BACKUP_DIR/appendonly_$DATE.aof
# 清理 7 天前备份
find $BACKUP_DIR -name "appendonly_*.aof.gz" -mtime +7 -delete
八、最佳实践
8.1 配置策略
| 场景 | 配置 |
|---|---|
| 高可用 | AOF everysec + RDB |
| 缓存 | 禁用 AOF |
| 金融 | AOF always + RDB |
| 一般 | AOF everysec + RDB |
8.2 混合持久化
# Redis 4.0+ 推荐配置
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
8.3 备份策略
每小时:本地 AOF 备份
每天:异地 AOF 备份
每周:归档 + 清理
九、常见问题
Q1: AOF vs RDB?
AOF:
- 数据更安全
- 文件较大
- 恢复慢
RDB:
- 紧凑,适合备份
- 恢复快
- 可能丢失数据
建议:同时开启
Q2: AOF 文件过大?
# 1. 触发重写
redis-cli BGREWRITEAOF
# 2. 调整重写配置
auto-aof-rewrite-percentage 50
auto-aof-rewrite-min-size 32mb
# 3. 检查大 Key
redis-cli --bigkeys
Q3: AOF 加载慢?
# 1. 启用混合持久化
aof-use-rdb-preamble yes
# 2. 减少 AOF 大小
定期 BGREWRITEAOF
# 3. 使用 SSD
Q4: 数据丢失怎么办?
# 1. 检查 AOF 文件
redis-check-aof --fix appendonly.aof
# 2. 从备份恢复
cp backup/appendonly.aof /var/lib/redis/
# 3. 重启 Redis
redis-server /etc/redis/redis.conf
总结
Redis AOF 核心要点:
| 特性 | 说明 |
|---|---|
| 格式 | Redis 协议日志 |
| 同步 | always/everysec/no |
| 优势 | 数据更安全 |
| 劣势 | 文件较大 |
| 适用 | 高可用场景 |
最佳实践:
- 使用 everysec 同步策略
- 启用混合持久化(Redis 4.0+)
- 配置自动重写
- 定期备份 AOF 文件
- 同时开启 RDB 备份
掌握 AOF,保障 Redis 数据安全!