3. PromQL 入门:Prometheus 数据模型、标签匹配与常用函数

PromQL(Prometheus Query Language)是 Prometheus 生态的核心查询语言,也是将原始指标数据转化为报警规则与可视化面板的基础。本节从数据模型出发,逐步讲解标签匹配机制与三个最常用的计算函数:rate、increase 和 histogram_quantile。

3.1 Prometheus 数据模型

Prometheus 存储的所有时间序列由 指标名称 和一组 标签(Label) 唯一标识。理解这一模型是编写正确 PromQL 的前提。

概念说明示例
Metric Name描述被监控对象的一般含义http_requests_total
Label键值对,用于区分同一指标的不同维度method="GET", status="200"
Sample一个时间点上的具体数值@timestamp 1234.56
Time Series同一 Metric + 同一 Label 组合的样本流http_requests_total{method="GET",status="200"}
核心原则: 标签是 Prometheus 数据模型的灵魂。一个指标名加上一组标签键值对,就构成一条独立的时间序列。报警规则与仪表盘查询都依赖标签来筛选和聚合数据。
数据模型结构示意:
http_requests_total{job="api-server", instance="10.0.1.5:9090", method="POST", status="500"}  = 7 @ 1710000000

其中 http_requests_total 是指标名,{job, instance, method, status} 是标签集合,7 是样本值,1710000000 是时间戳。

Prometheus 时间序列数据模型 Metric Name http_requests_total Label Set {job, instance, method, status} Sample Value 7 @ T Time Series = Metric Name + Label Set http_requests_total{job="api", method="GET", status="200"} 每个唯一的标签组合产生一条独立的时间序列,报警规则按标签聚合

3.2 标签匹配与选择器

PromQL 使用 标签匹配器(Label Matcher) 来筛选时间序列。匹配器写在花括号 {} 内,支持四种操作符:

匹配器含义示例匹配结果
=精确相等{status="200"}仅 status 为 "200" 的序列
!=不相等{status!="500"}排除 status 为 "500" 的序列
=~正则匹配{method=~"GET|POST"}method 为 GET 或 POST 的序列
!~正则排除{method!~"DELETE|PUT"}排除 method 为 DELETE 或 PUT 的序列
性能注意: 正则匹配(=~ 和 !~)比精确匹配消耗更多计算资源。在报警规则和仪表盘查询中,优先使用 = 和 !=,仅在需要模糊匹配时使用正则。

选择器示例:

# 精确匹配:查询所有 GET 请求的 200 响应总数
http_requests_total{method="GET", status="200"}

# 正则匹配:查询所有 4xx 或 5xx 状态码的请求
http_requests_total{status=~"4[0-9]{2}|5[0-9]{2}"}

# 多标签组合:查询生产环境 api 实例的 POST 请求
http_requests_total{job="api-prod", instance=~"10\\.0\\..*", method="POST"}
PromQL 标签匹配流程 原始时间序列 所有 http_requests_total 标签匹配器 {method="GET", status=~"2.."} 筛选后序列 仅 GET + 2xx 的序列 匹配器支持精确、不等、正则三种模式,可组合多个标签同时过滤 报警规则中常用精确匹配,仪表盘变量常用正则匹配实现动态过滤

3.3 常用函数:rate、increase 与 histogram_quantile

Prometheus 的 Counter 类型指标(如 http_requests_total)是单调递增的累计值,直接使用原始值没有意义。必须通过 rate 或 increase 函数将其转换为每秒速率或增量,才能反映真实变化。

3.3.1 rate() — 计算每秒平均增长率

rate(v range-vector) 计算时间范围内 Counter 指标的 每秒平均增长率。它是报警规则中最常用的函数,适用于检测突增或突降。

# 计算过去 5 分钟内,每秒平均请求数
rate(http_requests_total{status="500"}[5m])

# 在报警规则中使用:当 5xx 错误率超过 10 qps 时触发
rate(http_requests_total{status=~"5.."}[5m]) > 10
最佳实践: 在报警规则中,rate 的时间窗口建议设置为 1m、5m 或 10m。窗口太短(如 30s)容易抖动,太长(如 30m)会延迟报警响应。仪表盘面板通常使用 $__rate_interval 变量自动适配。

3.3.2 increase() — 计算时间范围内的增量

increase(v range-vector) 返回 Counter 在指定时间范围内的 总增量。与 rate 不同,它不除以时间秒数,直接给出原始增长值。

# 过去 1 小时内,总共发生了多少次 500 错误
increase(http_requests_total{status="500"}[1h])

# 对比:过去 5 分钟的总请求增量
increase(http_requests_total[5m])
函数输出单位适用场景报警规则示例
rate()每秒速率(qps)实时流量监控、突增检测rate(errors[5m]) > 5
increase()原始增量(count)周期汇总、容量规划increase(errors[1h]) > 1000
避坑提示: 不要对 Gauge 类型指标使用 rate 或 increase,它们只适用于 Counter。Gauge 指标(如 CPU 使用率、内存占用)应直接使用 avg_over_time 或 max_over_time 等聚合函数。

3.3.3 histogram_quantile() — 计算分位数

histogram_quantile(φ, bucket) 从 Histogram 类型的指标中计算 分位数(如 P50、P90、P99)。它需要配合 rate 或 increase 使用,将累积桶转换为速率后再计算。

# 计算过去 5 分钟内,请求延迟的 P99 值(单位:秒)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

# 计算 P50 和 P90
histogram_quantile(0.50, rate(http_request_duration_seconds_bucket[5m]))
histogram_quantile(0.90, rate(http_request_duration_seconds_bucket[5m]))
分位数解读:
  • P50(中位数): 50% 的请求延迟低于此值,反映典型体验。
  • P90: 90% 的请求延迟低于此值,排除长尾影响。
  • P99: 99% 的请求延迟低于此值,用于捕捉极端慢请求。

在报警规则中,通常对 P99 设置阈值,例如:histogram_quantile(0.99, rate(...)) > 2.0 表示 P99 延迟超过 2 秒时报警。

PromQL 常用函数关系图 Counter 指标 http_requests_total rate() 每秒速率 (qps) increase() 时间窗口增量 histogram_quantile() 分位数 (P50/P90/P99) rate() 和 increase() 只用于 Counter 类型;histogram_quantile() 需要配合 rate() 使用 报警规则中 rate 用于实时检测,increase 用于周期汇总,histogram_quantile 用于延迟 SLO

3.4 综合示例:构建一个延迟报警规则

将本节知识点串联起来,编写一个完整的 PromQL 报警规则:

# 报警规则:P99 延迟超过 2 秒,且持续 5 分钟
- alert: HighLatencyP99
  expr: |
    histogram_quantile(0.99,
      rate(http_request_duration_seconds_bucket{job="api-server"}[5m])
    ) > 2.0
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "API 服务 P99 延迟超过 2 秒 (当前值: {{ $value | humanizeDuration }})"
规则拆解:
  1. rate(...[5m]) — 将 Histogram 桶转换为每秒速率。
  2. histogram_quantile(0.99, ...) — 从速率桶中计算 P99 分位数。
  3. > 2.0 — 阈值条件:P99 延迟超过 2 秒。
  4. for: 5m — 持续 5 分钟满足条件才触发报警,避免毛刺误报。