登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis AOF 重写期间怎样观察写入缓冲增长

来源:17golang原创

时间:2026-11-14 03:49:56 296浏览 收藏

先说结论:Redis AOF 重写期间能否直接观察到“写入缓冲”,取决于 Redis 版本。Redis 7.0 之前,INFO persistence 可以看到 aof_rewrite_buffer_length;Redis 7.0 起改用多片段 AOF,官方字段说明已经标注这个字段被移除。此时不要盯着一个不存在的字段,而要同时观察重写状态、重写耗时、AOF 大小、COW 内存和磁盘余量。

官方地址:https://redis.io/

本文只讨论 AOF 重写期间的观测,不把示例输出当作本机运行结果,也不把 AOF 文件大小的增长直接等同于内存缓冲增长。

先看 Redis 7 之后的 AOF 重写链路

收到自动重写或 BGREWRITEAOF 后,Redis 会在后台准备新的 AOF。Redis 7.0 及以后,父进程继续接收写入,同时打开增量 AOF;子进程生成新的 base AOF,完成后再通过临时 manifest 和原子替换让新组合生效。写入增长因此首先体现为增量文件、AOF 总体大小和磁盘消耗,而不是旧版本那种“父进程把所有新命令堆在内存 rewrite buffer 中”。

Redis 7 及以后父进程、子进程、base AOF 和 incremental AOF 的重写生命周期静态说明图
图1:AOF 重写生命周期说明图,理解 Redis 7 之后写入不再汇总到旧式内存 rewrite buffer。

可以把这条链路拆成三个判断:

  • 是否在重写:看 aof_rewrite_in_progress。
  • 是否排队:看 aof_rewrite_scheduled 或相关 pending 字段,可能是另一个持久化子进程正在运行。
  • 是否完成:看 aof_last_bgrewrite_status、当前耗时归零,以及 AOF 文件状态是否回到稳定区间。

BGREWRITEAOF 只是发起请求,不代表新一轮已经同时启动。如果已有持久化子进程,或者 AOF 重写已经在进行,命令可能返回排队提示或错误。先读取状态,再决定是否需要继续排查。

用 INFO persistence 建立一份观测快照

生产环境建议读取 persistence 区段,并把采样时间一起保存。下面的命令只负责取数,注释说明每一步的目的:

# 读取 RDB 与 AOF 的持久化字段,便于判断当前是否在重写
redis-cli INFO persistence

# 只保留与 AOF 重写和文件增长有关的字段,减少人工阅读噪声
redis-cli INFO persistence | awk -F: '/^(aof_|rdb_bgsave_in_progress)/ {print}'

# 主动请求重写;若已有持久化子进程,先以返回信息和 INFO 状态为准
redis-cli BGREWRITEAOF

一次采样至少记录下面这些字段。字段可能随版本和构建变化,所以监控程序要允许字段缺失,不要把缺失直接当作数值 0。

字段看什么不要怎样误判
aof_rewrite_in_progress当前是否有 AOF 重写为 0 只说明当前没有进行中,不说明上次成功
aof_current_rewrite_time_sec本轮重写已持续多久时间长不一定失败,要结合写入量、磁盘和 COW
aof_current_size当前 AOF 组合的体积增长是文件层现象,不等于内存 buffer 增长
aof_base_size最近一次启动或重写后的基线体积与 current size 的差值要结合重写是否刚完成解读
aof_last_cow_size上一次 AOF 重写产生的 Copy-on-Write 内存量这是上一轮结果,不是当前实时 rewrite buffer
aof_last_bgrewrite_status上一次重写成功或失败成功不代表本轮仍在推进,失败也要结合错误日志处理
aof_last_write_statusAOF 最近写入状态不能替代磁盘空间和 fsync 延迟观察

正确理解 rewrite buffer 的版本差异

如果实例是 Redis 7.0 或更高版本,aof_rewrite_buffer_length 不再是可用的当前指标。不要因为监控查询不到它,就把结果补成 0,也不要把 aof_current_size - aof_base_size 直接命名为“内存缓冲”。两者的单位和生命周期不同:前者是旧实现里的内存缓冲,后者更接近 AOF 文件层面的增长。

在较旧版本中,如果这个字段存在,可以把它当作重写期间父进程积累的新写入量的一个观察窗口。写入速率高、子进程生成新 AOF 较慢时,该数值可能增长;重写完成并合并后,它应回到新的稳定状态。但即便在旧版本,也要同时看 aof_current_rewrite_time_sec、磁盘空间和内存,否则只看 buffer 会漏掉 COW 或 fsync 压力。

下面是一个版本无关的读取思路:先列出字段,再按存在性选择解释方式。示例使用 Python 标准库做文本解析,代码中的中文注释说明了缺失字段的处理:

from __future__ import annotations

import subprocess


def read_persistence() -> dict[str, str]:
    # 只读取 persistence 区段,避免把业务键值混入监控结果
    raw = subprocess.check_output(
        ["redis-cli", "--raw", "INFO", "persistence"], text=True
    )
    values: dict[str, str] = {}
    for line in raw.splitlines():
        # 跳过区段标题、空行和不带冒号的非字段行
        if not line or line.startswith("#") or ":" not in line:
            continue
        key, value = line.split(":", 1)
        values[key] = value
    return values


info = read_persistence()

# Redis 7+ 可能没有旧字段;缺失应显示为 unavailable,而不是伪造为 0
rewrite_buffer = info.get("aof_rewrite_buffer_length", "unavailable")
print("rewrite_buffer=", rewrite_buffer)
print("rewrite_in_progress=", info.get("aof_rewrite_in_progress", "unavailable"))
print("current_rewrite_time_sec=", info.get("aof_current_rewrite_time_sec", "unavailable"))

重复采样,判断增长是否失衡

单次快照只能回答“现在是什么状态”,不能回答“增长是否异常”。更实用的办法是按固定间隔采集一组字段,计算相邻样本的增量。对 Redis 7+,重点看 aof_current_size 在重写期间如何变化;对旧版本,再把 aof_rewrite_buffer_length 作为可选字段加入。

# 每 10 秒采集一行,保留时间戳与关键字段用于后续画趋势
while true; do
  # 记录样本时间,方便把 Redis 指标和磁盘监控对齐
  now=$(date -u +%FT%TZ)
  # 只抓取持久化字段;缺少的旧字段不在 shell 中强行补零
  redis-cli --raw INFO persistence | awk -v t="$now" \
    '/^(aof_rewrite_in_progress|aof_current_rewrite_time_sec|aof_current_size|aof_base_size|aof_last_cow_size|aof_last_bgrewrite_status|aof_rewrite_buffer_length):/ {print t, $0}'
  sleep 10
done

把趋势分成三个组合来读:

  1. 重写状态 + 时间:aof_rewrite_in_progress=1 且耗时持续增加,说明重写还没结束;如果时间很长,再结合日志和磁盘 I/O 判断是否卡在资源争用。
  2. AOF 增长 + 写入速率:重写期间 aof_current_size 上升,可能只是业务写入持续产生的增量文件。需要和正常业务写入基线比较,不能单独判定为内存泄漏。
  3. COW + 内存余量:重写基于 fork 和 Copy-on-Write,父进程写入越活跃,内存页复制压力可能越大。aof_last_cow_size 是上一轮结果,实时判断还应结合系统内存和 Redis 内存指标。
Redis AOF 重写期间 INFO persistence 指标、趋势采样、COW 与磁盘告警边界的静态关系说明图
图2:观测指标关系说明图,把重写状态、增长速度、COW 和磁盘余量放在同一个判断框架。

磁盘空间必须单独采样。Redis 7+ 的 base 文件、incremental 文件、临时文件和旧文件清理都可能在重写阶段产生空间峰值,不能只拿“重写后的最终 AOF 大小”估算峰值容量。

# 查看 AOF 所在文件系统的剩余空间,路径应替换为实例实际目录
df -h /var/lib/redis

# 查看持久化配置,确认自动重写阈值和 fsync 策略
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET appendfsync
# 查看自动重写的比例阈值,确认自动触发条件
redis-cli CONFIG GET auto-aof-rewrite-percentage

# 查看自动重写的最小 AOF 大小,避免小文件频繁重写
redis-cli CONFIG GET auto-aof-rewrite-min-size

这里的重点是把“何时触发重写”和“重写进行到哪一步”分开看。

把指标组合成告警和处置边界

不要设置一个“buffer 超过某个固定字节数就报警”的通用阈值,因为实例版本、数据集大小、写入速率和磁盘速度差异很大。更稳妥的是建立组合条件:

现象优先确认处理方向
重写持续很久且 current size 快速增长写入速率、磁盘写入延迟、CPU 和重写日志确认重写是否跟不上业务写入,必要时错峰或扩容磁盘 I/O
COW 较大且内存余量下降最近一次 COW、业务写入热点、系统可用内存避免在内存紧张时反复触发重写,先保留安全余量
磁盘余量下降但重写未结束AOF 目录、临时文件、base/incremental 文件先保证空间和写入安全,不要直接删除 Redis 正在使用的文件
aof_last_bgrewrite_status=failRedis 日志、文件权限、磁盘错误和子进程错误修复外部原因后再重试,不把失败当成指标抖动
监控查询不到 rewrite buffer 字段Redis 版本和 INFO 字段集合Redis 7+ 改用 current size、耗时、COW、磁盘等组合指标

如果只想确认一轮重写是否已经结束,可以先做一个最小判断:

# 读取状态并筛选最近一次重写结果;输出是示例读取方式,不是固定结果
redis-cli --raw INFO persistence | awk -F: \
  '/^(aof_rewrite_in_progress|aof_current_rewrite_time_sec|aof_last_bgrewrite_status|aof_last_cow_size):/ {print $1 "=" $2}'

当 aof_rewrite_in_progress 从 1 变为 0 后,再看 aof_last_bgrewrite_status 是否成功,并对比重写前后的 AOF 基线。不要在状态刚变更时立刻把所有旧文件当成异常;多片段 AOF 的文件切换和清理需要结合官方实现语义与实际磁盘状态判断。

排查清单与常见问题

  1. 记录 Redis 版本,确认是否是 Redis 7.0 及以后。
  2. 读取 INFO persistence,先判断是否正在重写或排队。
  3. 存在 aof_rewrite_buffer_length 时才解释旧式内存缓冲;字段缺失不要补零。
  4. 对 Redis 7+ 记录 aof_current_size、重写耗时、COW 和 AOF 目录磁盘余量。
  5. 固定间隔采样,观察增量和持续时间,不以单次值下结论。
  6. 重写失败时读取日志和文件系统错误,再决定是否重试。

Q:Redis 7+ 还能观察 AOF 重写期间的写入量吗?
可以观察文件层面的变化和写入趋势,但不能再把它叫作旧式 rewrite buffer。用 current size、base size、重写耗时和业务写入基线组合判断。

Q:aof_current_size - aof_base_size 就是写入缓冲吗?
不是。它是两个 AOF 体积指标的差值,可能包含增量 AOF 等文件层变化,不能直接代表进程内存占用。

Q:aof_last_cow_size 能代表当前内存压力吗?
不能。它通常描述上一轮重写的 COW 结果。当前重写期间还要结合系统可用内存、Redis 内存指标和业务写入速率。

总结一下:Redis AOF 重写的观测重点已经从“找一个 buffer 字段”变成“理解版本实现,再组合读取状态、耗时、文件增长、COW 和磁盘空间”。这样既能兼容旧版字段,也不会把 Redis 7+ 的增量文件误判成实时内存缓冲。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>