首页
/ Prometheus Agent 模式(--agent):面向大规模 Remote Write 采集的 WAL 轻量存储机制

Prometheus Agent 模式(--agent):面向大规模 Remote Write 采集的 WAL 轻量存储机制

2026-09-05 17:21:43作者:农烁颖Land

Prometheus 内置的 Agent 模式(通过 --agent 启动参数开启)是同一个二进制中的"采集 + 远端写"专用运行形态:它保留完整的抓取与服务发现逻辑,但关闭 TSDB 本地查询、告警与规则评估,用一套定制化的 WAL 存储替代本地数据库。本文基于仓库文档与 tsdb/agentcmd/prometheus 源码,讲解 Agent 模式的工作原理、全部专属启动参数及其默认值、配置文件的约束校验规则,帮助读者把 Prometheus 部署为低成本、可水平扩展的指标采集节点。

Prometheus Agent 远程写数据流:抓取端拉取指标后经定制化 WAL 批量写入远端存储

Agent 模式是什么:拉取不变,存储与查询被替换

Prometheus Agent 是与常规模式共用同一套抓取 API、语义、配置与服务发现机制的运维形态。它与普通 Prometheus 实例的差异在于:

  • 禁用常规特性:关闭 TSDB 本地块存储、告警(alerting)与规则(rules)评估,二进制针对"抓取 + 远端写"做了优化;
  • 数据转发基于 Remote Write 协议:Agent 将采集到的全部或一部分指标(可选择附带 metadata 与 exemplars)以流式(streaming)方式推送到一个或多个支持 Remote Write API 的端点;
  • 保持 pull 模型:Agent 依旧主动从目标应用拉取指标,因此继承了 pull 模型的故障发现能力;拉取到的样本随后被打包成 batch,复制(push)到远端端点,从而把"中心节点不可知"的监控盲区降到最低;
  • 支撑全局视图(Global View):将多个抓取节点的数据汇聚到中心化存储,实现应用团队与可观测性/监控管道团队的职责分离。

从源码结构看,Agent 模式的核心实现位于 tsdb/agent/db.go:其中定义的 DB 是一个"仅 WAL(write-ahead log)存储",它实现了 storage.DB 接口,但所有查询入口——QuerierChunkQuerierExemplarQuerier——一律返回 ErrUnsupported("unsupported operation with WAL-only storage"),从接口层面强制了"只能写、不能查"的语义:

// tsdb/agent/db.go
var ErrUnsupported = errors.New("unsupported operation with WAL-only storage")

// Querier implements the Storage interface.
func (*DB) Querier(int64, int64) (storage.Querier, error) {
	return nil, ErrUnsupported
}

Agent 模式的收益与代价

文档明确列出了 Agent 模式的收益与局限,两者都直接对应源码中的实现行为:

收益

  1. 效率更高:定制的 Agent WAL 在数据成功写入远端后会立即删除本地数据;若远端端点暂时不可达,数据会临时持久化到磁盘等待恢复。这个本地缓冲目前与常规 Prometheus 一样受限,最长约 2 小时。由于不需要在内存中构建数据 chunk、也不需要为查询维护完整索引,Agent 在同等负载下使用的资源只是普通 Prometheus 服务器的一小部分。
  2. 更简单的采集端水平扩展:多个 Agent 实例可以横向部署,各自独立抓取并转发,天然支持大规模指标摄取。

代价(三条硬性限制)

限制 说明 源码/配置依据
无本地查询 不能向本地 Prometheus 实例发起查询 tsdb/agent/db.goQuerier 返回 ErrUnsupported
无记录规则 不能预先聚合/汇总再发送到 Remote Write,规则必须在远端执行 配置校验禁止 rule_files(见下文配置约束)
无告警 所有告警必须由远端系统完成 配置校验禁止 alerting

启动方式:--agent 与 Agent 专属参数

运行 prometheus --help 可以看到与 Agent 模式直接相关的参数:

usage: prometheus [<flags>]

The Prometheus monitoring server

Flags:
  -h, --help                     Show context-sensitive help (also try --help-long and --help-man).
      (... other flags)
      --storage.tsdb.path="data/"
                                 Base path for metrics storage. Use with server mode only.
      --storage.agent.path="data-agent/"
                                 Base path for metrics storage. Use with agent mode only.
      (... other flags)
      --[no-]agent               Run Prometheus in 'Agent mode'.

加上 --agent 即以 Agent 模式启动。其余参数要么两种模式共用,要么只属于其中一种——参数帮助字符串的最后一句会标明(例如 "Use with server mode only" 表示仅限 server 模式;没有此类标注则为共用参数)。

cmd/prometheus/main.go 可以看到,所有 Agent 专属参数都通过 agentOnlyFlag 注册,并在启动时做互斥校验:Agent 模式下传入 server-only 参数、或 server 模式下传入 agent-only 参数,进程都会直接报错退出。

当前仓库中 Agent 模式的完整专属参数如下(默认值取自 main.go 注册逻辑与 tsdb/agent/db.go 的常量定义):

参数 默认值 作用
--agent false 开启 Agent 模式
--storage.agent.path data-agent/ Agent WAL 存储根目录(仅 Agent 模式)
--storage.agent.retention.min-time 5m 数据在 WAL 中被删除前的最短存活时间,用于给远端写失败留重试窗口
--storage.agent.retention.max-time 4h 数据在 WAL 中的最长存活时间,防止远端长期不可达时 WAL 无限增长
--storage.agent.wal-truncate-frequency 2h(隐藏参数) WAL 截断/检查点(checkpoint)的触发周期
--storage.agent.wal-segment-size wlog 默认段大小(隐藏参数) 单个 WAL 段文件的最大字节数,启用时须在 10MB~256MB 之间
--storage.agent.wal-compression true 是否压缩 WAL 记录;为 true 时按 wal-compression-type 选择算法
--storage.agent.wal-compression-type snappy(隐藏参数,可选 snappy/zstd WAL 压缩算法
--storage.agent.checkpoint-from-in-memory-series false 构建 checkpoint 时只使用内存中的序列数据,避免回读磁盘上的旧 checkpoint 与段文件
--storage.agent.checkpoint-batch-size 1000 单个 WAL 日志条目分片的刷新大小;仅在上一参数开启时生效,且必须大于 0
--storage.agent.no-lockfile false 不在数据目录创建 lockfile

其中保留时间的两个默认值来自 tsdb/agent/db.go

var (
	DefaultTruncateFrequency = 2 * time.Hour
	DefaultMinWALTime        = int64(5 * time.Minute / time.Millisecond)
	DefaultMaxWALTime        = int64(4 * time.Hour / time.Millisecond)
)

validateOptions 还保证了一致性约束:若 MinWALTime > MaxWALTime 则把 MaxWALTime 拉平为 MinWALTime;若 MaxWALTime 小于截断周期,也会自动下调,避免"刚写入就要被截断"的矛盾状态。

WAL 数据生命周期:截断、检查点与 2 小时缓冲

文档中"成功写入后立即删除、失败时最长 2 小时缓冲"的描述,对应 tsdb/agent/db.gorun() 的周期截断循环。其截断水位(watermark)计算逻辑非常值得细看:

// tsdb/agent/db.go  run() 中的核心逻辑(简化)
ts := max(db.rs.LowestSentTimestamp()-db.opts.MinWALTime, 0)

// 网络故障可能导致 LowestSentTimestamp 不前进,
// 因此对数据最大年龄设置上限,超过则向前推进截断水位
if maxTS := timestamp.FromTime(time.Now()) - db.opts.MaxWALTime; ts < maxTS {
    ts = maxTS
}
db.truncate(ts)

可以这样理解其工作流:

  1. 远端写进度驱动:截断水位基于 remote.Storage.LowestSentTimestamp()(所有远端写端点中最低的已发送时间戳)减去 MinWALTime(默认 5 分钟),即"远端确认收过、再留 5 分钟缓冲"的数据即可安全删除;
  2. 兜底上限:若远端长期不可达导致水位停滞,MaxWALTime(默认 4 小时,但受 MaxWALTime < TruncateFrequency 时自动取 TruncateFrequency 的影响,实际数据最长保留约一个截断周期量级)会强制推进水位,这就是文档所说"目前限制在两小时缓冲量级"的来源——它保证磁盘占用有界;
  3. 序列 GCtruncate 先执行 gc(mint),把最近样本时间戳早于水位且已不再活跃的序列标记为待删除(deleted 映射),再推进 WAL 段;
  4. 检查点与段清理truncate 对 WAL 下约前 2/3 的段做 checkpoint(把仍需保留的 series 记录写入 checkpoint 目录),随后截断更早的段并清理旧 checkpoint;checkpoint 支持两种实现——默认回扫 WAL 段,或开启 --storage.agent.checkpoint-from-in-memory-series 后仅用内存序列分批(CheckpointBatchSize 控制批大小)写出,减少磁盘回读;
  5. 重启回放:进程重启时 replayWAL 先加载最近 checkpoint、再回放其后的 WAL 段,重建内存中的 stripeSeries(ref → 标签集 → 最后样本时间戳)映射;遇到损坏的 WAL 会自动尝试 Repair

围绕这一生命周期,Agent 还暴露了一组可观测指标(见 db.godbMetrics),例如 prometheus_agent_active_seriesprometheus_agent_samples_appended_totalprometheus_agent_truncate_duration_secondsprometheus_agent_data_replay_duration_secondsprometheus_agent_checkpoint_creations_total 等,便于监控截断与回放是否健康。

配置约束:Agent 模式拒绝 alerting、rule_files 与 remote_read

Agent 模式接受与常规模式完全相同的 scrape 配置、服务发现选项与 Remote Write 选项。但对不适用的顶层配置段,加载时会直接报错,而不是静默忽略。校验逻辑位于 config/config.go

if agentMode {
    // ...
    return nil, errors.New("field alerting is not allowed in agent mode")
    // ...
    return nil, errors.New("field rule_files is not allowed in agent mode")
    // ...
    return nil, errors.New("field remote_read is not allowed in agent mode")
}

仓库测试数据目录 config/testdata 中有一组针对性样例,清晰展示了这些约束的"正反两面":

文件 内容 结果
agent_mode.good.yml 仅配置 remote_write Agent 模式合法配置
agent_mode.with_alert_manager.yml 配置 alerting.alertmanagers Agent 模式报错
agent_mode.with_rule_files.yml 配置 rule_files Agent 模式报错
agent_mode.with_remote_reads.yml 配置 remote_read Agent 模式报错
agent_mode.without_remote_writes.yml 仅有 global.scrape_interval: 15s,无 remote_write 用于验证 remote_write 的校验
agent_mode.with_alert_relabels.yml 告警 relabel 配置 Agent 模式报错(告警相关)

一个最简的 Agent 模式配置文件形如(对应 agent_mode.good.yml):

remote_write:
  - url: http://remote1/push

其余抓取配置(scrape_configs、各类 *_sd_configs)与常规模式写法完全一致,无需任何改动。

Web 管理界面:只读、无查询

Agent 模式同样在 9095 端口(Prometheus 默认 HTTP 端口)暴露 Web UI。从 cmd/prometheus/main.go 可见启动时会将 cfg.web.IsAgent = agentMode 传入 Web 层,据此禁用查询入口。因此管理界面与常规 Prometheus 一致地展示构建信息(build info)、当前配置(configuration)、目标(targets)与服务发现信息,但查询能力被置为不可用——这与"无本地查询"的限制在 UI 层面保持一致。运维上这意味着 Agent 节点依然可以通过管理 API 检查抓取目标健康状态,便于排障,但不能用它做数据回溯。

适用场景与选型建议

结合上述机制,Agent 模式的适用边界可以归纳为:

  • 适合:把抓取/摄取层与存储/查询层分离的架构——多个 Agent 实例分布抓取(利用完整的服务发现能力),统一推送到支持 Remote Write 的中心化存储;需要控制内存与磁盘占用的大规模采集场景;
  • 不适合:需要在本地做 PromQL 查询、记录规则预聚合或本地告警的场景——这些必须保留常规 server 模式,或将规则与告警下放到远端存储系统执行。

启动一个最小 Agent 实例的命令为:

prometheus --config.file=prometheus.yml --agent

如需调整 WAL 行为,可追加本文"启动方式"一节表格中的 --storage.agent.* 参数;配置文件中则只需提供 remote_write 与常规 scrape_configs。所有行为的最终依据可追溯至 docs/prometheus_agent.mdtsdb/agent/db.gocmd/prometheus/main.goconfig/config.go

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384