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 将会记录一条警告。

  • 从 Prometheus v3.8 开始,功能开关 native-histograms 已被弃用。请改用新的 scrape_native_histograms 全局和每个抓取任务的配置选项。

配置

  • 抓取作业级别的配置选项 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 格式和降级

Prometheus v2.55 中对 TSDB 格式进行了轻微更改,为索引格式的更改做准备。因此,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 采用了 log/slog,取代了之前的 go-kit/log。这导致了日志消息格式的改变。旧日志格式的一个例子是:

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

lequantile 标签值

在 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 文档

本页内容