3.1 四种表达式类型
- Instant Vector 即时向量
- 一组序列在同一时刻各有一个样本。
http_requests_total就返回即时向量。 - Range Vector 区间向量
- 一组序列在一段时间窗口内的多个样本。用
[5m]语法得到,如http_requests_total[5m],只能喂给 rate 类函数。 - Scalar 标量
- 单个浮点数,如
3.14,或scalar()的结果。 - String 字符串
- 仅少数函数使用,实际查询中很少直接返回。
3.2 选择器与匹配
# 精确匹配
http_requests_total{job="api", status="500"}
# 正则匹配 =~ ,取反 != / !~
http_requests_total{status=~"5.."} # 所有 5xx
http_requests_total{handler!="/health"} # 排除健康检查
http_requests_total{env=~"prod|staging"} # 多值
# 区间向量 + 偏移
http_requests_total[5m] # 最近 5 分钟
http_requests_total offset 1h # 1 小时前的即时值
3.3 rate / irate / increase
Counter 只增不减,直接看没意义。rate 计算区间内的每秒平均增长率,是 PromQL 里最常用的函数。
# 每秒请求数(QPS),5 分钟窗口平滑
rate(http_requests_total[5m])
# irate:只用窗口内最后两个点,反应更灵敏但更抖,适合快变化
irate(http_requests_total[1m])
# increase:区间内的总增量(= rate * 窗口秒数)
increase(http_requests_total[1h]) # 过去 1 小时总请求数
rate 的窗口要 ≥ 4×抓取间隔
rate 至少需要窗口内有两个样本才能算。若 scrape_interval 是 15s,窗口至少给 [1m](含约 4 个点),否则可能出现空结果或抖动。rate 还会自动处理 counter reset(重启归零)。
3.4 聚合算子
聚合算子把多条序列压成更少的序列。核心是 by(保留哪些 label)和 without(去掉哪些 label)。
# 全站总 QPS(去掉所有维度,聚合成一条)
sum(rate(http_requests_total[5m]))
# 按状态码分组的 QPS
sum by (status) (rate(http_requests_total[5m]))
# 每个实例的内存使用,保留 instance
avg by (instance) (node_memory_used_bytes)
# Top 3 最忙的接口
topk(3, sum by (handler) (rate(http_requests_total[5m])))
常用聚合算子:sum / avg / min / max / count / count_values / stddev / topk / bottomk / quantile。
3.5 常用函数
| 函数 | 作用 |
|---|---|
histogram_quantile(0.95, ...) | 从 _bucket 序列估算 P95 分位数 |
rate() / irate() / increase() | Counter 速率与增量 |
delta() / deriv() | Gauge 的变化量 / 导数 |
predict_linear(v[1h], 3600) | 线性预测未来值(如磁盘几时写满) |
avg_over_time(v[5m]) | 区间内时间加权平均(同类还有 max/min/sum_over_time) |
label_replace() / label_join() | 动态改写 / 拼接标签 |
clamp_max() / round() | 数值裁剪与取整 |
算 P95 延迟
histogram_quantile(
0.95,
sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
)
注意:先对 _bucket 做 rate + sum by (le)(跨实例聚合),再喂给 histogram_quantile——这正是 Histogram 能跨实例聚合的原因。
3.6 二元算子与向量匹配
# 算术:错误率(5xx 占比)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
# 比较 + bool:延迟是否超标(返回 0/1)
node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.1
# on/ignoring 控制向量匹配的 label 维度
rate(errors_total[5m]) / on(instance) rate(requests_total[5m])
向量匹配 on / ignoring / group_left
两个向量做运算时,Prometheus 按 label 集合配对。用 on(labels) 指定按哪些 label 匹配,ignoring(labels) 反向;一对多用 group_left/group_right——这是 PromQL 最难的部分,常见于 info 指标 join。
3.7 常见查询模式速查
- CPU 使用率(node_exporter)
100 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100- 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100- 目标存活数
sum by(job)(up)——某 job 有几个目标在线。- 磁盘几小时写满
predict_linear(node_filesystem_avail_bytes[6h], 4*3600) < 0- QPS by 接口
sum by(handler)(rate(http_requests_total[5m]))- P99 延迟
histogram_quantile(0.99, sum by(le)(rate(request_duration_seconds_bucket[5m])))
3.8 小结与下一步
- 先分清即时向量 vs 区间向量:只有区间向量能喂 rate 类函数。
- Counter → rate → sum by 是最经典的三连;分位数用 histogram_quantile 配 sum by(le)。
- 二元算子的向量匹配(on/ignoring/group_left)是进阶难点,多练。
- 下一章讲 配置与服务发现——告诉 Prometheus 去哪儿抓这些数据。