Prometheus 3.0 迁移指南

根据我们的 稳定性承诺,Prometheus 3.0 版本包含多项向后不兼容的更改。本文档提供了从 Prometheus 2.x 迁移到 Prometheus 3.0 及更高版本的指南。

标志

  • 以下特性标志已移除,并已加入 Prometheus v3 的默认行为中

    • promql-at-modifier
    • promql-negative-offset
    • new-service-discovery-manager
    • expand-external-labels
      • 外部标签值中的环境变量引用 ${var}$var 将根据当前环境变量的值进行替换。
      • 对未定义变量的引用将替换为空字符串。$ 字符可以通过使用 $$ 进行转义。
    • no-default-scrape-port
      • Prometheus v3 将不再根据指定的方案向抓取目标添加端口。目标现在将按配置显示在标签中。
      • 如果您依赖像 https://example.com/metricshttp://example.com/metrics 这样的抓取目标分别表示为 https://example.com/metrics:443http://example.com/metrics:80,请将它们添加到您的目标 URL 中
    • agent
      • 请改用专用的 --agent CLI 标志。
    • remote-write-receiver
      • 请改用专用的 --web.enable-remote-write-receiver CLI 标志来启用远程写入接收器。
    • auto-gomemlimit
      • Prometheus v3 将自动设置 GOMEMLIMIT 以匹配 Linux 容器内存限制。如果没有容器限制,或者进程在容器外部运行,则使用系统总内存。要禁用此功能,可以使用 --no-auto-gomemlimit
    • auto-gomaxprocs
      • Prometheus v3 将自动设置 GOMAXPROCS 以匹配 Linux 容器 CPU 配额。要禁用此功能,可以使用 --no-auto-gomaxprocs

    如果您继续将这些标志传递给 --enable-feature,Prometheus v3 将记录警告。

配置

  • 抓取作业级别的配置选项 scrape_classic_histograms 已重命名为 always_scrape_classic_histograms。如果您使用 --enable-feature=native-histograms 特性标志来摄取原生直方图,并且还想摄取端点可能与原生直方图一起暴露的经典直方图,请务必添加此配置或将您的配置从旧名称更改过来。
  • remote_write 项中的 http_config.enable_http2 默认值已更改为 false。在 Prometheus v2 中,远程写入 HTTP 客户端默认使用 HTTP/2。为了在多个套接字上并行化多个远程写入队列,最好不要默认使用 HTTP/2。如果您希望远程写入使用 HTTP/2,现在必须在 remote_write 配置部分中设置 http_config.enable_http2: true

PromQL

正则表达式匹配换行符

PromQL 正则表达式中的 . 模式现在匹配换行符。通过此更改,像 .* 这样的正则表达式将匹配包含 \n 的字符串。这适用于查询中的匹配器和 relabel 配置。

例如,以下正则表达式现在可以匹配相应的字符串,而在 Prometheus v2 中这些组合不匹配。 - .* 额外匹配 foo\nFoo\nBar - foo.?bar 额外匹配 foo\nbar - foo.+bar 额外匹配 foo\nbar

如果您希望 Prometheus v3 的行为与 v2 相同,您必须更改正则表达式,将所有 . 模式替换为 [^\n],例如 foo[^\n]*

范围选择器和回溯排除与左边界重合的样本

回溯和范围选择器现在是左开右闭(以前是左闭右闭),这使得它们的行为更加一致。此更改影响那些范围左边界或回溯增量与一个或多个样本时间戳重合的查询。

例如,假设我们正在查询一个时间序列,其中样本间隔均匀,正好相隔 1 分钟。在 Prometheus v3 之前,一个带有 5m 的范围查询通常会返回 5 个样本。但如果查询评估与抓取完美对齐,它将返回 6 个样本。在 Prometheus v3 中,像这样的查询在样本间隔均匀的情况下将始终返回 5 个样本。

此更改通常会影响子查询,因为它们的评估时间自然是完美均匀分布的,并与子查询分辨率的倍数时间戳对齐。此外,查询前端通常将子查询对齐到步长的倍数。结合起来,这很容易造成完美相互对齐的情况,这通常是用户无意中或不知道的,因此新行为可能会出乎意料。在 Prometheus V3 之前,在这样的系统上,像 foo[1m:1m] 这样的子查询可能总是返回两个点,从而允许进行速率计算。然而,在 Prometheus V3 中,这样的子查询将只返回一个点,这对于速率或增量计算来说是不够的,导致返回“无数据”。

此类查询需要重写以扩展窗口,以正确覆盖一个以上的点。在此示例中,foo[2m:1m] 都将始终返回两个点,无论查询对齐方式如何。重写查询的具体形式可能取决于预期的结果,并且对于行为已更改的查询,没有通用的直接替代方案。

测试也更容易受到影响。要解决这些问题,请调整预期的样本数量或扩展范围。

holt_winters 函数已重命名

holt_winters 函数已重命名为 double_exponential_smoothing,现在受 promql-experimental-functions 特性标志保护。如果您想继续使用 holt_winters,则必须执行以下两项操作

  • 在您的查询中将 holt_winters 重命名为 double_exponential_smoothing
  • 在您的 Prometheus CLI 调用中传递 --enable-feature=promql-experimental-functions

抓取协议

Prometheus v3 对抓取时接收到的 Content-Type 头部更加严格。如果被抓取的目标未指定 Content-Type 头部,或者该头部无法解析或无法识别,Prometheus v2 会默认使用标准 Prometheus 文本协议。这可能导致抓取中解析出不正确的数据。Prometheus v3 在此类情况下现在将使抓取失败。

如果抓取目标未提供正确的 Content-Type 头部,可以使用 fallback_scrape_protocol 参数指定回退协议。请参阅 Prometheus scrape_config 文档

这是一项破坏性更改,因为在 Prometheus v2 中可能成功的抓取,如果未指定此回退协议,现在可能会失败。

杂项

TSDB 格式与降级

TSDB 格式在 Prometheus v2.55 中略有更改,以准备索引格式的更改。因此,Prometheus v3 TSDB 只能由 Prometheus v2.55 或更高版本读取。在升级到 v3 时请记住这一点——您只能降级到 v2.55,不能更低,否则将丢失您的 TSDB 持久化数据。

作为一项额外的安全措施,您可以选择先升级到 v2.55 并确认 Prometheus 运行正常,然后再升级到 v3。

TSDB 存储契约

现在,TSDB 兼容存储预期返回与指定选择器匹配的结果。这可能会影响一些第三方实现,最可能是实现 remote_read 的那些。

此契约未明确强制执行,但可能导致未定义行为。

UTF-8 名称

Prometheus v3 支持指标和标签名称中的 UTF-8。这意味着升级后,指标和标签名称可以根据端点暴露的内容而改变。此外,以前被标记为无效的指标和标签名称将不再被标记为无效。

希望保留原始验证行为的用户可以更新其 Prometheus yaml 配置,以指定旧版验证方案

global:
  metric_name_validation_scheme: legacy

或者按每次抓取

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

日志消息格式

Prometheus v3 已从之前的 go-kit/log 切换到 log/slog。这导致日志消息格式发生变化。旧日志格式的示例如下:

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)"

le 和 quantile 标签值

在 Prometheus v3 中,经典直方图的 le 标签值和摘要的 quantile 标签值在摄取时会被规范化。在 Prometheus v2 中,这些标签的值在某些情况下取决于抓取协议(protobuf 与文本格式)。这导致标签值根据抓取协议而变化。例如,一个暴露为 my_classic_hist{le="1"} 的指标通过文本格式摄取时仍为 my_classic_hist{le="1"},但通过 protobuf 摄取时则为 my_classic_hist{le="1.0"}。这改变了指标的标识,并在查询指标时导致问题。在 Prometheus v3 中,这些标签值将始终规范化为浮点数表示。也就是说,无论通过哪种协议,上述示例都将始终导致 my_classic_hist{le="1.0"} 被摄取到 Prometheus 中。此更改的影响是,直接引用整数标签值(例如 le="1")的告警、记录规则和仪表盘将停止工作。

处理此更改的方法,无论是全局性的还是针对每个指标的:

  • 修复对整数 lequantile 标签值的引用,但除此之外不做任何更改,并接受一些跨越过渡时间的查询将产生不准确或意外的结果。这是推荐的解决方案。
  • 使用 metric_relabel_config 在抓取目标时保留旧标签。这应该应用于当前生成此类标签的指标。
    metric_relabel_configs:
      - source_labels:
          - quantile
        target_label: quantile
        regex: (\d+)\.0+
      - source_labels:
          - le
          - __name__
        target_label: le
        regex: (\d+)\.0+;.*_bucket

禁止使用 v1 API 配置 Alertmanager

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

Prometheus 2.0 迁移指南

有关从 Prometheus 1.8 迁移到 2.0 的指南,请参阅 Prometheus v2.55 文档

本页内容