Redis AOF 重写期间怎样观察写入缓冲增长
先说结论: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 中”。

可以把这条链路拆成三个判断:
- 是否在重写:看
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_status | AOF 最近写入状态 | 不能替代磁盘空间和 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
把趋势分成三个组合来读:
- 重写状态 + 时间:
aof_rewrite_in_progress=1且耗时持续增加,说明重写还没结束;如果时间很长,再结合日志和磁盘 I/O 判断是否卡在资源争用。 - AOF 增长 + 写入速率:重写期间
aof_current_size上升,可能只是业务写入持续产生的增量文件。需要和正常业务写入基线比较,不能单独判定为内存泄漏。 - COW + 内存余量:重写基于 fork 和 Copy-on-Write,父进程写入越活跃,内存页复制压力可能越大。
aof_last_cow_size是上一轮结果,实时判断还应结合系统内存和 Redis 内存指标。

磁盘空间必须单独采样。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=fail | Redis 日志、文件权限、磁盘错误和子进程错误 | 修复外部原因后再重试,不把失败当成指标抖动 |
| 监控查询不到 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 的文件切换和清理需要结合官方实现语义与实际磁盘状态判断。
排查清单与常见问题
- 记录 Redis 版本,确认是否是 Redis 7.0 及以后。
- 读取
INFO persistence,先判断是否正在重写或排队。 - 存在
aof_rewrite_buffer_length时才解释旧式内存缓冲;字段缺失不要补零。 - 对 Redis 7+ 记录
aof_current_size、重写耗时、COW 和 AOF 目录磁盘余量。 - 固定间隔采样,观察增量和持续时间,不以单次值下结论。
- 重写失败时读取日志和文件系统错误,再决定是否重试。
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+ 的增量文件误判成实时内存缓冲。
Redis BITFIELD 怎样存储多个小整数并读取指定范围
- 上一篇
- Redis BITFIELD 怎样存储多个小整数并读取指定范围
- 下一篇
- Redis eviction 触发后为什么带 TTL 的键不一定先被删除
-
- 数据库 · Redis | 29分钟前 | Redis · 缓存 · redis TTL maxmemory-policy eviction
- Redis eviction 触发后为什么带 TTL 的键不一定先被删除
- 484浏览 收藏
-
- 数据库 · Redis | 34分钟前 |
- Redis BITFIELD 怎样存储多个小整数并读取指定范围
- 266浏览 收藏
-
- 数据库 · Redis | 36分钟前 | redis集群 · Redis Cluster MOVED ASK hash slot resharding CLUSTER SETSLOT
- Redis Cluster resharding 时怎样减少业务请求的 MOVED
- 297浏览 收藏
-
- 数据库 · Redis | 36分钟前 | redis hyperloglog 去重 PFADD PFCOUNT 基数估算
- Redis HyperLogLog 估算去重数为什么不能取回原始成员
- 155浏览 收藏
-
- 数据库 · Redis | 38分钟前 | 排行榜 · Sorted Set · redis 分页 排行榜 有序集合 ZRANGE
- Redis ZRANGE 怎样按分数和成员稳定读取排行榜
- 189浏览 收藏
-
- 数据库 · Redis | 41分钟前 | redis集群 · redis Redis Cluster CROSSSLOT Hash Tag CLUSTER KEYSLOT
- Redis CROSSSLOT 错误怎样用 key tag 重写键名
- 460浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 1018次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 1020次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1155次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1121次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 962次使用
-
- Redis Stream XTRIM 如何避免消费组积压无限增长
- 2026-09-12 501浏览
-
- Redis AOF rewrite 期间如何判断磁盘与内存压力
- 2026-09-12 501浏览
-
- Redis RDB 和 AOF 怎么按可接受数据丢失量选择
- 2026-09-08 501浏览
-
- Redis XAUTOCLAIM 之后为什么仍有 pending:JUSTID、PEL 与消息删除边界
- 2026-08-29 501浏览
-
- Redis SET 的 GET 与 KEEPTTL 怎么一起验收:旧值返回、续期与回滚边界
- 2026-08-20 501浏览

