PromQL 详解:Prometheus 查询语言完全指南

PromQL 查询语言全解析

PromQL 详解:Prometheus 查询语言完全指南

PromQL(Prometheus Query Language)是 Prometheus 的查询语言,用于选择和聚合时间序列数据。它是 Prometheus 可观测性的核心,支持从简单的指标查询到复杂的多维分析、告警规则定义和趋势预测。

本文将全面、系统地讲解 PromQL 的语法、数据类型、函数、操作符、查询模式和最佳实践,帮助你掌握从入门到高级的 PromQL 技能。


一、PromQL 核心概念

1. 数据模型回顾

Prometheus 的数据由 时间序列(Time Series) 组成,每条序列由:

  • 指标名称(Metric Name)
  • 标签(Labels)
  • 样本(Samples)(timestamp, value) 数据点

2. PromQL 的三大数据类型

类型说明示例
瞬时向量(Instant Vector)某一时刻的多条时间序列http_requests_total{job="api"}
范围向量(Range Vector)一段时间内的多条时间序列http_requests_total[5m]
标量(Scalar)简单数字(无时间序列)123, 3.14

PromQL 查询结果通常是瞬时向量或标量


二、基础查询语法

1. 瞬时向量选择器(Instant Vector Selector)

查询某一时刻的指标数据。

基本语法
metric_name{label_key="value", ...}
示例
# 所有 http_requests_total 指标
http_requests_total

# 过滤 job="api-server" 的指标
http_requests_total{job="api-server"}

# 多标签过滤
http_requests_total{job="api-server", status="500"}

# 使用正则匹配
http_requests_total{method=~"GET|POST"}     # =~ 表示正则匹配
http_requests_total{instance!~".*:9090"}    # != 表示不等于,!~ 表示不匹配正则

2. 范围向量选择器(Range Vector Selector)

查询过去一段时间内的指标数据,用于计算速率、分位数等。

语法
metric_name[<duration>]
  • <duration>:时间范围,如 5m, 1h, 2d
示例
# 过去 5 分钟的所有样本
http_requests_total[5m]

# 过去 1 小时的请求耗时
http_request_duration_seconds[1h]

✅ 范围向量不能直接显示,必须配合函数使用(如 rate())。


三、PromQL 操作符

1. 算术操作符

操作符说明
+, -, *, /, %, ^加减乘除、取模、幂运算
示例
# 计算错误率
rate(http_requests_total{status="500"}[5m]) / rate(http_requests_total[5m])

# 内存使用百分比
(node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes

2. 比较操作符

操作符说明
==, !=等于、不等于
>, <, >=, <=大于、小于等
== bool, != bool返回布尔值(用于过滤)
示例
# 返回值 > 100 的时间序列
node_filesystem_avail_bytes > 100

# 返回布尔结果(0 或 1)
node_filesystem_avail_bytes > bool 100

3. 逻辑/集合操作符

操作符说明
and交集(保留两边都存在的序列)
or并集(合并序列)
unless差集(左边存在但右边不存在)
示例
# 保留 job="api" 且 status="500" 的序列
http_requests_total{job="api"} and http_requests_total{status="500"}

# 合并两个指标
http_requests_total{job="api"} or http_requests_total{job="frontend"}

# 排除特定实例
http_requests_total unless http_requests_total{instance="backup"}

四、核心函数详解

1. rate()irate()

计算每秒增长率,用于 Counter 指标。

rate(counter[range])
  • 计算区间内的平均增长率
  • 平滑,适合告警和图表
# 过去 5 分钟平均每秒请求数
rate(http_requests_total[5m])
irate(counter[range])
  • 计算最近两个样本的增长率
  • 对波动敏感,适合瞬时变化检测
# 最近两次抓取的增长率
irate(http_requests_total[5m])

生产推荐rate() 用于告警,irate() 用于瞬时监控。


2. increase()

计算时间范围内 Counter 的增长总量

# 过去 1 小时请求数
increase(http_requests_total[1h])

✅ 等价于 rate() * 时间秒数,但返回整数。


3. sum(), avg(), min(), max(), count()

聚合函数,支持 bywithout 分组。

语法
sum by (label1, label2) (vector)
示例
# 按 job 聚合请求总数
sum by (job) (rate(http_requests_total[5m]))

# 按 method 统计平均耗时
avg by (method) (rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))

# 统计实例数量
count without (instance) (up)

by:保留指定标签;without:去掉指定标签。


4. histogram_quantile()

从 Histogram 中计算分位数

语法
histogram_quantile(<phi>, <vector>)
  • phi:分位数(0.5, 0.95, 0.99)
  • <vector>_bucket 指标
示例
# 计算 99 分位响应延迟
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, job))

# 计算 P95
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[10m]))

✅ 必须对 _bucket 使用 rate() 并按 le 分组。


5. topk()bottomk()

返回前 N 个或后 N 个序列。

# 请求最多的前 5 个实例
topk(5, sum by (instance) (rate(http_requests_total[5m])))

# 延迟最低的 3 个服务
bottomk(3, avg by (job) (http_request_duration_seconds))

6. delta()changes()

delta(gauge[range])
  • 计算 Gauge 在区间内的变化量
  • 适用于周期性重置的 Gauge
# 磁盘使用量变化
delta(node_filesystem_size_bytes[1h])
changes(gauge[range])
  • 计算 Gauge 在区间内的变化次数
# 状态变化次数
changes(process_state[1h])

7. resets()

计算 Counter 在区间内的重置次数(如进程重启)。

# 过去 1 小时重启次数
resets(process_start_time_seconds[1h])

8. absent()present()

检查指标是否存在。

# 如果 no_such_metric 不存在,返回 1
absent(no_such_metric)

# 如果 up 为 0,表示实例宕机
absent(up{job="api"} == 1)

✅ 常用于告警规则中检测实例宕机。


五、高级查询模式

1. 计算平均耗时(Timer / Histogram)

# 方法 1:Sum / Count
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

# 方法 2:使用 histogram_quantile 计算分位数
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))

2. 计算错误率

# 5xx 错误率
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])

3. 计算成功率

# 2xx + 3xx 占比
sum(rate(http_requests_total{status=~"2..|3.."}[5m])) by (job) 
/ sum(rate(http_requests_total[5m])) by (job)

4. 预测磁盘耗尽时间

# 预测磁盘在多少小时内耗尽
node_filesystem_avail_bytes / rate(node_filesystem_avail_bytes[1h])

六、PromQL 在告警规则中的应用

# rules/alerts.yml
groups:
  - name: example
    rules:
      - alert: HighRequestLatency
        expr: >
          histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
          > 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High latency on {{ $labels.job }}"
          description: "99th percentile latency is > 1s for 10 minutes."

      - alert: InstanceDown
        expr: absent(up{job="api"} == 1)
        for: 5m
        annotations:
          description: "{{ $labels.instance }} has disappeared from Prometheus."

七、PromQL 性能优化建议

优化项建议
✅ 避免大范围查询1h7d 快得多
✅ 使用 rate() 而不是 increase() 做速率计算更稳定
✅ 聚合时使用 by 明确分组避免隐式聚合
✅ 避免高基数标签会导致查询变慢
✅ 使用 Recording Rules 预计算复杂查询提升查询性能
✅ 合理设置 scrape_interval与查询范围匹配

八、常用 PromQL 查询速查表

需求PromQL 查询
每秒请求数rate(http_requests_total[5m])
错误率rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
P99 延迟histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
平均耗时rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])
实例是否存活up == 1
CPU 使用率1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)
内存使用率(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes
磁盘剩余node_filesystem_avail_bytes / node_filesystem_size_bytes

九、总结

PromQL 是 Prometheus 的灵魂,掌握它意味着你能:

  • ✅ 实时监控系统健康
  • ✅ 精准定位性能瓶颈
  • ✅ 编写有效的告警规则
  • ✅ 实现复杂的可观测性分析

学习路径建议:

  1. 基础:瞬时/范围向量、算术操作
  2. 核心rate(), sum(), histogram_quantile()
  3. 进阶relabel 结合查询、Recording Rules
  4. 实战:Grafana 面板 + 告警规则

📌 官方文档https://prometheus.io/docs/prometheus/latest/querying/basics/

通过不断练习和实践,PromQL 将成为你排查问题、保障系统稳定的最强武器。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值