Skip to content
清晨的一缕阳光
返回

Redis AOF 持久化详解

Redis AOF 持久化详解

AOF(Append Only File)是 Redis 的日志式持久化机制,通过记录每个写操作实现数据持久化。本文将深入 AOF 的原理、配置和优化。

一、AOF 基础概念

1.1 什么是 AOF

AOF 是操作日志

写操作                 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
优势数据更安全
劣势文件较大
适用高可用场景

最佳实践

  1. 使用 everysec 同步策略
  2. 启用混合持久化(Redis 4.0+)
  3. 配置自动重写
  4. 定期备份 AOF 文件
  5. 同时开启 RDB 备份

掌握 AOF,保障 Redis 数据安全!

参考资料


分享这篇文章到:

上一篇文章
RAG 性能优化实战指南
下一篇文章
三国志之曹操