首页
/ Prometheus 3.0 迁移指南:破坏性变更全解与源码级迁移实践

Prometheus 3.0 迁移指南:破坏性变更全解与源码级迁移实践

2026-09-03 17:21:25作者:戚魁泉Nursing

本文围绕 Prometheus 3.0 的官方迁移指南(docs/migration.md)展开,系统梳理从 Prometheus 2.x 升级到 3.0 及更高版本时的全部破坏性变更,涵盖已移除的 feature flag、配置项改名与默认值变化、PromQL 语义调整、Scrape 协议收紧、TSDB 格式约束、UTF-8 命名支持、日志格式切换等关键主题,并结合当前仓库源码给出每一项变更的底层实现证据与可操作的迁移方案。读完本文,你可以独立完成一次 2.x → 3.x 的升级,并能解释每项变更在源码中的具体落点。

一、背景:为什么 Prometheus 3.0 是破坏性发布

按照 Prometheus 的稳定性承诺(docs/stability.md),3.0 版本引入了一批向后不兼容的变更。这些变更大多是把曾经隐藏在 feature flag 背后的实验特性"转正"为默认行为,同时清理了一批历史遗留的边界情况。对使用者而言,升级前需要逐项核对本文列出的变更点,尤其是涉及 PromQL 查询语义、Scrape 协议和 le/quantile 标签值的部分——它们会静默改变既有查询、告警和看板的结果。

二、Flags:被移除的 feature flag 与专属 CLI 参数

2.1 已转正并移除的 feature flag

以下 feature flag 在 3.0 中被移除,其能力已并入默认行为。继续在 --enable-feature 中传递它们只会收到警告:

  • promql-at-modifier@ <timestamp> 时间修饰符已默认支持;
  • promql-negative-offset:负数偏移量已默认支持;
  • new-service-discovery-manager:新服务发现管理器已成为默认实现;
  • expand-external-labels:外部标签值中的环境变量引用 ${var}$var 现在会按当前环境变量的值展开,未定义的变量替换为空字符串,$$ 用于转义 $ 字符;
  • no-default-scrape-port:Prometheus v3 不再按 scheme 为抓取目标自动补端口。目标在标签中将原样呈现。如果你依赖 https://example.com/metrics 被表示为 https://example.com/metrics:443http://example.com/metrics 被表示为 http://example.com/metrics:80 的旧行为,需要自行在目标 URL 中显式写上端口;
  • agent:改为使用专属的 --agent CLI flag(见下文);
  • remote-write-receiver:改为使用专属的 --web.enable-remote-write-receiver flag 来启用 remote write 接收端点;
  • auto-gomemlimit:v3 会自动将 GOMEMLIMIT 设置为与 Linux 容器内存限制一致;没有容器限制或进程运行在容器外时,使用系统总内存。可通过 --no-auto-gomemlimit 关闭;
  • auto-gomaxprocs:v3 会自动将 GOMAXPROCS 设置为与 Linux 容器 CPU 配额一致。可通过 --no-auto-gomaxprocs 关闭。

从源码可以确认这些变更的落点:

  • cmd/prometheus/main.go 中注册了专属的 --agent flag:a.Flag("agent", "Run Prometheus in 'Agent mode'.").BoolVar(&agentMode),而 agent 专属的存储参数(--storage.agent.path--storage.agent.retention.min-time 等)均通过 agentOnlyFlag 辅助函数注册(cmd/prometheus/main.go#L174-L180),并在 server 模式下校验冲突;
  • remote write 接收端点对应的 flag 定义在 cmd/prometheus/main.go#L478a.Flag("web.enable-remote-write-receiver", "Enable API endpoint accepting remote write requests.")
  • auto-gomemlimit / auto-gomaxprocs 现在以普通 CLI flag 形式存在,并附带 --auto-gomemlimit.ratio--auto-gomemlimit.refresh-interval 等调参选项(cmd/prometheus/main.go#L435-L441),支持在运行时(如 Vertical Pod Autoscaler 场景)周期性地重新探测内存限制。

2.2 native-histograms 自 v3.9 起成为 no-op

从 v3.9 开始,feature flag native-histograms 不再有任何效果。原生直方图已成为稳定特性,但抓取它需要通过配置显式开启:在全局或每个 scrape job 中设置 scrape_native_histograms(该配置选项在 v3.8 引入)。

源码印证:--enable-feature=native-histograms 现在只会打出一条警告(cmd/prometheus/main.go#L266-L267):

case "native-histograms":
    logger.Warn("This option for --enable-feature is a no-op. To scrape native histograms, set the scrape_native_histograms scrape config setting to true.", "option", o)

对应的配置字段分别定义在 config/config.go 的 GlobalConfig(ScrapeNativeHistograms *bool,对应 scrape_native_histograms)和 config/config.go#L809 的 ScrapeConfig 中。

三、Configuration:配置项改名与默认值变化

3.1 scrape_classic_histograms 改名为 always_scrape_classic_histograms

抓取 job 级配置项 scrape_classic_histograms 已改名为 always_scrape_classic_histograms。如果你使用 scrape_native_histograms 抓取原生直方图,同时又希望保留端点可能一并暴露的经典直方图,务必新增(或从旧名迁移)该配置,否则会丢失经典直方图数据。

源码中该字段以指针类型区分"未设置"与"显式设置",全局级在 config/config.go#L538AlwaysScrapeClassicHistograms bool),scrape job 级在 config/config.go#L811AlwaysScrapeClassicHistograms *bool),job 级配置可覆盖全局默认。仓库测试数据中也提供了多个相关示例,例如 config/testdata/local_enable_always_scrape_classic_hist.good.ymlconfig/testdata/global_convert_classic_hist_to_nhcb.good.yml,可用于核对新旧名称的写法差异。

3.2 remote_writehttp_config.enable_http2 默认值改为 false

remote_write 配置中 http_config.enable_http2 的默认值由 true 变为 false。在 v2 中 remote write 的 HTTP 客户端默认使用 HTTP/2;但在 v3 中,为了让多个 remote write 队列能够并行地跑在多个 socket 上,默认不再使用 HTTP/2 更合适。如果你希望 remote write 继续走 HTTP/2,需要在 remote_write 配置段中显式设置:

remote_write:
  - url: "http://ingest.example.com:4001/api/v1/write"
    http_config:
      enable_http2: true

四、PromQL:三个语义层面的行为变更

4.1 正则表达式中的 . 现在匹配换行符

PromQL 中正则表达式的 . 模式现在可以匹配换行符 \n。这同时作用于查询匹配器和 relabel 配置中的正则。以下组合在 v2 中不匹配,在 v3 中会匹配:

  • .* 额外匹配 foo\nFoo\nBar
  • foo.?bar 额外匹配 foo\nbar
  • foo.+bar 额外匹配 foo\nbar

如果你希望 v3 保持 v2 的行为,需要把所有 . 替换为 [^\n],例如将 foo.* 改写为 foo[^\n]*

4.2 范围选择器与回看窗口左边界改为"开"

Range 选择器与 lookback 选择器由原来的"左闭右闭"变为左开右闭,行为更加一致。该变更只影响范围/回看窗口的左边界恰好与某个样本时间戳重合的查询。

一个直观的例子:假设某时间序列样本恰好以 1 分钟均匀间隔产生。在 v2 中,[5m] 范围查询通常返回 5 个样本,但如果查询评估时刻恰好与一次抓取对齐,会返回 6 个样本;v3 中这类查询在均匀间隔下总是返回 5 个样本

该变更对子查询(subquery)影响尤为突出,因为子查询的评估时刻天然等距且对齐到子查询分辨率的整数倍,而查询前端又常把子查询对齐到 step 的整数倍——多重对齐叠加后极易形成用户无意的"完美对齐"。例如,在这样完全对齐的系统中,v2 里 foo[1m:1m] 可能一直返回两个点,足以做 rate 计算;而 v3 中同一子查询只返回一个点,无法进行 rate/increase 计算,结果是 No Data

迁移方式是把窗口拉长,确保覆盖多于一个点。上例中 foo[2m:1m] 无论查询如何对齐都返回两个点。具体改写形式取决于预期结果,不存在普适的一键替换方案。测试同样容易受影响,修复方式是调整期望的样本数或扩大范围。

4.3 holt_winters 函数改名并被实验性 flag 守护

holt_winters 函数已改名为 double_exponential_smoothing,并且现在受 promql-experimental-functions feature flag 守护。要继续使用该函数,必须同时完成两件事:

  1. 将查询中的 holt_winters 改写为 double_exponential_smoothing
  2. 在启动命令行中传递 --enable-feature=promql-experimental-functions

源码印证:cmd/prometheus/main.go#L261-L263 中该 flag 会设置 c.parserOpts.EnableExperimentalFunctions = true,将实验性函数开关传递给 PromQL 解析器。

五、Scrape 协议:Content-Type 校验收紧(破坏性变更)

Prometheus v3 对抓取时收到的 Content-Type 头更加严格

  • v2 的行为:目标未指定 Content-Type、或头无法解析/不被识别时,默认回退到标准 Prometheus 文本协议。这可能导致抓取数据被错误解析;
  • v3 的行为:上述情况下直接判定抓取失败

如果某个抓取目标无法提供正确的 Content-Type 头,可以使用 fallback_scrape_protocol 参数显式指定回退协议。该参数在源码中的字段为 config/config.go#L807ScrapeFallbackProtocol ScrapeProtocol(YAML key fallback_scrape_protocol),其合法性校验在 config/config.go#L986 完成,支持的取值包括 OpenMetricsText0.0.1/1.0.0/2.0.0、PrometheusProto、PrometheusText0.0.4/1.0.0。仓库中的正/反示例可以直接参考:

这是一个破坏性变更:过去在 v2 下可能"歪打正着"成功的抓取,在 v3 中若未指定回退协议将失败。请确保抓取端点返回以下受支持的 Content-Type 之一:

  • application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited
  • text/plain;version=0.0.4
  • text/plain;version=1.0.0
  • application/openmetrics-text;version=0.0.1
  • application/openmetrics-text;version=1.0.0

六、Miscellaneous:存储、命名、日志与通知的其余变更

6.1 TSDB 格式与降级限制

TSDB 格式在 v2.55 中已为索引格式变更做了微调。由此带来一条硬约束:v3 的 TSDB 只能被 v2.55 或更新版本读取。升级到 v3 后,你最多只能降级回 v2.55,再低就会丢失 TSDB 持久化数据。官方给出的额外保险措施是:先升级到 v2.55、确认运行正常后,再升级到 v3。

6.2 TSDB 兼容存储的查询契约

TSDB 兼容的存储现在必须返回与指定选择器相匹配的查询结果。这主要影响第三方实现,尤其是实现了 remote_read 的服务。该契约不会被显式强制执行,违反它可能导致未定义行为。

6.3 UTF-8 指标名与标签名

v3 支持在指标名和标签名中使用 UTF-8。这意味着升级后,指标和标签名可能随端点实际暴露的内容发生变化;此前会被判为非法的名称现在将合法通过。如果希望保留旧版校验行为,可在配置中指定 legacy 校验方案:

全局配置:

global:
  metric_name_validation_scheme: legacy

或按 scrape job 粒度配置:

scrape_configs:
  - job_name: job1
    metric_name_validation_scheme: utf8
  - job_name: job2
    metric_name_validation_scheme: legacy

仓库中的 config/testdata/metric_name_validation_scheme.bad.yml 展示了该字段对非法取值的校验。

6.4 日志消息格式:从 go-kit/log 切换到 log/slog

v3 的日志底层从 go-kit/log 迁移到了标准库 log/slog(仓库中对应 util/logging 模块),日志字段名与格式随之变化。旧格式示例:

ts=2024-10-23T22:01:06.074Z caller=main.go:627 level=info msg="No time or size retention was set so using the default time retention" duration=15d
ts=2024-10-23T22:01:06.074Z caller=main.go:671 level=info msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=91d80252c3e528728b0f88d254dd720f6be07cb8-modified)"
ts=2024-10-23T22:01:06.074Z caller=main.go:676 level=info build_context="(go=go1.23.0, platform=linux/amd64, user=, date=, tags=unknown)"
ts=2024-10-23T22:01:06.074Z caller=main.go:677 level=info host_details="(Linux 5.15.0-124-generic #134-Ubuntu SMP Fri Sep 27 20:20:17 UTC 2024 x86_64 gigafips (none))"

新格式对应输出:

time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:640 msg="No time or size retention was set so using the default time retention" duration=15d
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:681 msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=7c7116fea8343795cae6da42960cacd0207a2af8)"
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:686 msg="operational information" build_context="(go=go1.23.0, platform=linux/amd64, user=, date=, tags=unknown)" host_details="(Linux 5.15.0-124-generic #134-Ubuntu SMP Fri Sep 27 20:20:17 UTC 2024 x86_64 gigafips (none))" fd_limits="(soft=1048576, hard=1048576)" vm_limits="(soft=unlimited, hard=unlimited)"

要点:ts 变为 timecaller 变为 sourcelevel=info 变为 level=INFO。如果你有基于日志字段的采集管道或告警规则,需要同步更新解析逻辑。

6.5 lequantile 标签值在摄入时归一化

v3 中,经典直方图 le 标签和 summary quantile 标签的值在摄入时统一归一化。v2 中这些标签的取值在某些情况下依赖抓取协议(protobuf 与文本格式不一致),例如端点暴露的 my_classic_hist{le="1"} 经文本格式摄入为 my_classic_hist{le="1"},经 protobuf 摄入却变成 my_classic_hist{le="1.0"}——这改变了指标的身份,给查询带来困扰。v3 中无论哪种协议,最终一律归一化为浮点表示,即总是摄入 my_classic_hist{le="1.0"}

直接后果:任何把 lequantile 值写为整数的告警、记录规则与看板(如 le="1")在升级后将停止工作。

官方给出的两种应对方式:

  • 推荐方案:修正所有对整数形式 lequantile 值的引用,接受跨越升级时刻的某些查询结果可能不准确;
  • 备选方案:在抓取目标时使用 metric_relabel_configs 还原旧标签。对确实产生这类标签的指标应用:
metric_relabel_configs:
  - source_labels:
      - quantile
    target_label: quantile
    regex: (\d+)\.0+
  - source_labels:
      - le
      - __name__
    target_label: le
    regex: (\d+)\.0+;.*_bucket

6.6 禁止通过 v1 API 配置 Alertmanager

Prometheus 3 不再支持 Alertmanager 的 v1 API,事实上要求 Alertmanager 0.16.0 或更新版本。仍在使用旧版本或 alerting: alertmanagers: [api_version: v1] 配置的用户,需要升级 Alertmanager 并将配置改为 api_version: v2

七、Agent 模式:从 feature flag 到专属 flag

在 2.x 中,Agent 模式通过 --enable-feature=agent 开启;v3 起必须改用专属的 --agent CLI flag。Agent 模式将 Prometheus 变成一个只负责本地抓取与 remote write 的轻量代理:它不保留长期查询存储(依赖 WAL),也不做本地 PromQL 查询,数据通过 remote write 送往全局层(如 Prometheus、Cortex、Thanos 等),架构示意如下:

Prometheus Agent 模式架构:Agent 在集群内抓取应用并做服务发现,通过 remote write 将数据送往全局 Prometheus/Cortex/Thanos 层

源码中,--agent flag 在 cmd/prometheus/main.go#L658 注册;开启 agent 模式后,一批 --storage.agent.* 参数生效(如 WAL 路径、保留时长、WAL 压缩等,见 cmd/prometheus/main.go#L556-L596),同时 server 专属 flag 会被校验拒绝(cmd/prometheus/main.go#L712),保证两种模式不混用。更详细的模式说明见 docs/prometheus_agent.md

八、迁移清单与降级策略速查

变更点 影响 迁移动作
9 个 feature flag 移除 --enable-feature 中出现被警告的项 清理命令行;agent/remote-write-receiver 改用专属 flag
native-histograms no-op(v3.9+) 原生直方图抓取行为 改设 scrape_native_histograms 全局/job 配置
scrape_classic_histograms 改名 同时需要经典+原生直方图 改用 always_scrape_classic_histograms
remote_write HTTP/2 默认关闭 写链路性能特征 需要时显式 http_config.enable_http2: true
正则 . 匹配换行 匹配器/relabel 命中范围扩大 需要旧行为则改为 [^\n]
范围/回看窗口左开右闭 完全对齐时样本数减少,子查询可能 No Data 拉长窗口,如 foo[1m:1m]foo[2m:1m]
holt_winters 改名 实验性函数不可用 改名 + --enable-feature=promql-experimental-functions
Content-Type 严格校验 抓取直接失败 端点返回受支持头,或配置 fallback_scrape_protocol
TSDB 版本约束 无法降级到 v2.55 之前 先升 v2.55 验证,再升 v3
UTF-8 名称 指标/标签名可能变化 需要旧校验则设 metric_name_validation_scheme: legacy
日志格式切换 日志解析/采集管道 更新 ts/caller/level 等字段的解析
le/quantile 归一化 le="1" 类引用失效 修正为 le="1.0",必要时用 metric_relabel_configs
Alertmanager v1 API 移除 通知链路中断 升级 Alertmanager ≥ 0.16.0,配置改用 api_version: v2

最后需要说明适用前提:本指南以当前仓库版本(v3 系列,native-histograms 已为 no-op 的 v3.9+ 状态)为准,从 v2 的任意版本升级前,建议先按 docs/installation.md 核对运行环境要求,并优先采用"v2.55 中转验证"的稳妥路径。如果你还在 1.x 时代,Prometheus 2.0 的迁移请参考 2.55 版本的官方迁移文档,本文不再展开。

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

项目优选

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