3. Prometheus 数据模型:理解 Metric、Label、Sample、Time Series,为聚合查询打基础

在排查误差预算台账数据偏差时,我们面对的是海量的时间序列数据。要精准地使用 PromQL 进行聚合查询,首先必须理解 Prometheus 底层的数据模型。这个模型定义了数据如何被采集、存储和标识,是编写任何有效查询的基石。

3.1 核心概念:四大要素

Prometheus 的数据模型由四个核心要素构成,它们共同定义了一个唯一的时间序列。

要素 定义 在误差预算场景中的示例
Metric(指标) 被监控的特定度量项的名称,描述“测量什么”。 http_request_duration_seconds(HTTP 请求耗时)
Label(标签) 键值对,用于对指标进行多维度的特征描述,描述“如何测量”。 service="checkout", status="500", method="POST"
Sample(样本) 一个具体的数据点,包含一个时间戳和一个值。 t=1700000000, v=0.95(在时间 t 时,P95 延迟为 0.95 秒)
Time Series(时间序列) 由 Metric 名称和一组唯一 Label 组合定义的、按时间排序的样本流。 http_request_duration_seconds{service="checkout", status="200"} 的所有历史样本。
关键理解: 一个 Metric 可以衍生出无数个 Time Series,每个 Time Series 由一组唯一的 Label 组合来区分。聚合查询的本质,就是通过 PromQL 操作,将多个 Time Series 合并计算成一个结果。

3.2 数据模型结构图

下图直观地展示了 Metric、Label、Sample 和 Time Series 之间的关系。一个 Metric 名称加上一组唯一的 Label 组合,就定义了一个 Time Series,而 Time Series 则是由一系列按时间排序的 Sample 组成的。

Prometheus 数据模型:从 Metric 到 Time Series Metric(指标) http_req_duration_sec Label 组合 {service="checkout", status="200"} + Time Series 唯一标识的数据流 = Sample 序列 t1, v1 t2, v2 t3, v3 t4, v4 包含

3.3 深入理解各要素

3.3.1 Metric(指标)

Metric 名称通常反映被监控对象的业务或技术含义。命名遵循 a-z, 0-9, 下划线和冒号。在误差预算场景中,常见的 Metric 包括:

  • slo_ratio:服务等级目标达成率。
  • error_budget_burn_rate:错误预算消耗速率。
  • http_requests_total:HTTP 请求总数。

3.3.2 Label(标签)

Label 是 Prometheus 数据模型实现多维可观测性的核心。通过不同的 Label 组合,我们可以从不同维度切分数据。在排查偏差时,错误的 Label 值或缺失的 Label 是常见的数据源。

排查技巧: 当聚合查询结果与预期不符时,首先检查参与计算的 Time Series 的 Label 组合。使用 {__name__="your_metric"} 查询所有 Series,确认 Label 的键和值是否正确。

3.3.3 Sample(样本)

每个样本由两部分组成:

  • Timestamp(时间戳):毫秒精度,表示数据采集的时刻。
  • Value(值):一个 64 位浮点数,代表该时刻的度量值。

在 PromQL 中,我们通过 @ 修饰符或范围向量选择器来操作样本的时间维度。

3.3.4 Time Series(时间序列)

一个 Time Series 由 Metric 名称 + 一组唯一的 Label 组合 唯一标识。例如:

http_requests_total{job="api-server", instance="10.0.0.1:9090", method="GET", status="200"}

这是一个独立的 Time Series。如果 status 变为 500,则是一个全新的 Time Series。聚合查询(如 sum by (service))的作用,就是将多个 Time Series 按照指定的 Label 维度进行合并计算。

3.4 数据模型与聚合查询的关系

理解数据模型是编写正确 PromQL 的前提。下表总结了数据模型要素与聚合查询操作之间的对应关系:

数据模型要素 在聚合查询中的作用 常见错误
Metric 指定聚合操作的目标数据集。 Metric 名称拼写错误,导致查询不到数据。
Label 定义聚合的维度(by 子句)或过滤条件({} 选择器)。 在 by 子句中遗漏了关键 Label,导致结果粒度太粗;或使用了不存在的 Label 值。
Sample 提供参与聚合计算的原始数值。 忽略了样本的时间范围(如 [5m]),导致计算了错误时间窗口的数据。
Time Series 聚合操作的基本单元。聚合函数将一组 Time Series 合并为一个或一组新的 Time Series。 未意识到高基数 Label(如 user_id)会导致大量 Time Series,使聚合查询性能下降或结果不准确。
高基数陷阱: 在误差预算台账中,避免将 user_id、request_id 等具有极高基数的值作为 Label。这会导致 Time Series 数量爆炸,不仅影响 Prometheus 性能,也会使聚合查询结果难以解读。应使用 service、status、slo_name 等低基数 Label。

3.5 数据模型在偏差排查中的实际应用

假设我们有一个误差预算指标 error_budget_remaining,其 Label 包括 service、slo_name 和 window。当我们发现某个服务的预算消耗异常时,排查路径如下:

  1. 确认 Metric 存在: 查询 {__name__="error_budget_remaining"},确认数据正在被采集。
  2. 检查 Label 维度: 查看返回的 Time Series,确认 service="checkout" 的 Label 值是否正确,是否存在拼写错误(如 service="checkout " 带空格)。
  3. 分析样本值: 使用 error_budget_remaining{service="checkout"}[1h] 查看过去一小时的样本值变化,确认是突然下降还是持续消耗。
  4. 聚合验证: 使用 sum by (service) (error_budget_remaining) 查看所有服务的总预算,与单个服务对比,确认偏差是否由数据聚合方式引起。

通过以上步骤,我们可以系统性地定位数据偏差的根因,是数据采集问题、Label 配置问题,还是 PromQL 查询逻辑问题。