PromQL(Prometheus Query Language)作为 Prometheus 的核心查询语言,其设计哲学源于对时间序列数据的高效处理需求。与传统的 SQL 不同,PromQL 专门为监控场景优化,具备以下三个显著特征:
在实际监控系统中,我们常见的查询模式包括:
关键理解:Prometheus 中每个时间序列由
<metric_name>{<label1>=<value1>,...}唯一标识,这比传统以名称区分的监控系统提供了更灵活的查询维度。
最基本的查询形式是直接使用指标名称:
promql复制node_cpu_seconds_total
这等价于:
promql复制node_cpu_seconds_total{}
实际生产环境中,我们通常需要添加标签过滤条件。例如查询特定实例的 CPU 使用情况:
promql复制node_cpu_seconds_total{instance="10.0.0.1:9100"}
PromQL 提供四种匹配操作符:
=:精确匹配!=:排除匹配=~:正则匹配!~:正则排除典型应用场景:
promql复制# 查询生产环境非 idle 状态的 CPU 时间
node_cpu_seconds_total{env="production", mode!="idle"}
# 查询多个服务的 HTTP 请求量
http_requests_total{service=~"user|order|payment"}
范围查询通过 [<duration>] 语法实现,用于分析时间窗口内的数据变化。常见时间单位包括:
示例:获取最近 5 分钟的 HTTP 请求量
promql复制http_requests_total[5m]
实战经验:范围查询通常与速率函数(如
rate())配合使用,计算指标变化率。例如计算 QPS:promql复制rate(http_requests_total[5m])
offset 关键字允许我们查询历史数据,这在同比分析中特别有用:
promql复制# 对比今天和昨天的同一时段流量
rate(http_requests_total[1h] offset 1d)
PromQL 支持标准的算术运算,但需要注意:
典型应用:
promql复制# 计算内存使用率
(node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes * 100
布尔运算符默认会过滤掉不满足条件的序列。使用 bool 修饰符可以保留所有序列并返回 0/1 值:
promql复制# 找出 CPU 使用率超过 80% 的实例
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance) > 0.8
# 获取布尔结果而非过滤
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance) > bool 0.8
三种集合运算符的行为差异:
and:交集or:并集unless:差集示例:找出有高 CPU 使用但内存使用正常的实例
promql复制(avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance) > 0.8)
and
(node_memory_MemFree_bytes / node_memory_MemTotal_bytes > 0.2)
PromQL 提供 11 种聚合函数,最常用的包括:
sum():求和avg():平均值min()/max():极值count():计数quantile():分位数by 和 without 控制聚合维度:
promql复制# 按实例分组计算 CPU 使用率
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance)
# 排除 instance 标签后聚合
sum(http_requests_total) without (instance)
promql复制# 找出请求量最高的 3 个接口
topk(3, sum(rate(http_requests_total[5m])) by (handler))
promql复制# 计算响应时间的 95 分位
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
rate() 或 increase() 处理 Counter 类型explain 参数查看查询执行计划promql复制# 服务错误率报警规则
(sum(rate(http_requests_total{status_code=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)) > 0.01
promql复制# 基于线性预测判断磁盘将在何时写满
predict_linear(node_filesystem_free_bytes[6h], 3600*24) < 0
四个黄金指标的 PromQL 实现:
rate(http_requests_total[5m])rate(http_requests_total{status_code=~"5.."}[5m])histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes掌握这些 PromQL 技巧后,你将能够:
在实际使用中,我发现最有效的学习方式是通过具体业务场景来练习 PromQL 查询。例如,尝试为你当前负责的服务构建完整的监控指标体系,从基础资源监控到业务指标监控,这个过程会强迫你深入理解各种 PromQL 特性的适用场景。