PromQL 从入门到实战:一篇让小白也能看懂的查询语言指南

PromQL 从入门到实战:一篇让小白也能看懂的查询语言指南
前言在上一篇文章中我们学习了 Prometheus 的 Relabeling 机制掌握了如何对监控目标进行筛选和标签转换。然而数据采集只是第一步——如何从海量监控数据中快速提取有价值的信息才是衡量监控系统价值的关键。PromQLPrometheus Query Language正是这把打开数据宝库的钥匙。它是 Prometheus 内置的函数式查询语言用于实时筛选、聚合和分析时间序列数据。无论是构建 Grafana 监控大屏还是配置告警规则都离不开 PromQL。本文将从零开始用最通俗的语言和大量实例带你掌握 PromQL 的核心用法。一、理解 PromQL 的基本概念在开始写查询之前先搞清楚三个核心概念——瞬时向量、区间向量和标量。1.1 三种数据类型类型含义示例瞬时向量Instant Vector一组时间序列每个序列只有一个最新的采样值node_cpu_seconds_total区间向量Range Vector一组时间序列每个序列包含一段时间内的多个采样值node_cpu_seconds_total[5m]标量Scalar一个单独的浮点数没有时间戳10、3.14用一句话理解瞬时向量就像快照——此时此刻每个指标的值是多少区间向量就像录像——过去5分钟每个指标的变化过程标量就是一个数字——没有任何附加信息1.2 最简单的查询瞬时向量最基本的 PromQL 查询就是直接写一个指标名称promqlnode_cpu_seconds_total这条查询会返回所有node_cpu_seconds_total时间序列的最新值。加上标签过滤可以精确筛选promqlnode_cpu_seconds_total{cpu0, modeidle}这里的{cpu0, modeidle}就是标签过滤器——只返回 cpu 为 0、mode 为 idle 的数据。支持的比较运算符运算符含义等于!不等于~正则匹配!~正则不匹配promql# 排除 cpu0只保留 user 和 system 模式 node_cpu_seconds_total{cpu!0, mode~user|system}二、二元运算符号PromQL 支持在查询中对数据进行各种运算。2.1 算术运算符运算符含义加法-减法*乘法/除法%取模求余数^幂运算向量与标量运算将向量中的每一个值与标量进行运算。promql# 所有内存值乘以 2 node_memory_MemFree_bytes * 2 # 所有 CPU 使用时间除以 100 node_cpu_seconds_total / 100向量与向量运算将左边向量的每个元素与右边向量中标签匹配的元素进行运算。promql# 计算内存使用率 (node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes * 1002.2 比较运算符运算符含义等于!不等于大于小于大于等于小于等于比较运算符默认会过滤掉不满足条件的数据promql# 只保留可用内存大于 100MB 的序列 node_memory_MemFree_bytes 100 * 1024 * 1024如果只想比较而不过滤加上bool关键字结果返回 1真或 0假promqlnode_memory_MemFree_bytes bool 100 * 1024 * 10242.3 逻辑/集合运算符运算符含义and交集——同时存在于左右两边or并集——存在于左边或右边unless差集——存在于左边但不在右边promql# 只保留 up1 的主机 up 1 and node_cpu_seconds_total # 合并两个查询结果 up{jobprometheus} or up{jobnode}三、聚合操作聚合函数的作用是将多个时间序列合并成一个或几个。它们只能用于瞬时向量。3.1 常用聚合函数函数含义sum()求和min()最小值max()最大值avg()平均值count()计数stddev()标准差topk(k, v)前 k 个最大值bottomk(k, v)后 k 个最小值quantile(φ, v)分位数φ 在 0~1 之间3.2 基础用法promql# 所有服务器的 CPU 空闲时间总和 sum(node_cpu_seconds_total{modeidle}) # 所有服务器的最大可用内存 max(node_memory_MemFree_bytes) # 所有服务器的平均内存使用率 avg((node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes)3.3 分组聚合by 和 without聚合时如果不分组所有数据会合并成一个结果。使用by或without可以按维度分组。by (label)只保留指定标签按这些标签分组。promql# 按实例分组计算每个实例的 CPU 空闲时间总和 sum(node_cpu_seconds_total{modeidle}) by (instance) without (label) 移除指定标签用剩余的标签分组。 promql # 移除 cpu 标签用其他标签分组 sum(node_cpu_seconds_total{modeidle}) without (cpu)实战示例promql# 每个服务的 QPS按 job 分组 sum(rate(http_requests_total[5m])) by (job) # 每个实例的 CPU 使用率 100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance) * 100)四、瞬时向量匹配当两个向量进行运算时PromQL 需要决定哪个元素和哪个元素配对。这就涉及向量匹配Vector Matching。4.1 一对一匹配默认默认情况下PromQL 会找标签完全一致的元素进行配对。promqlnode_memory_MemFree_bytes node_memory_Cached_bytes只有当两个指标的标签完全相同时才会相加。如果标签不完全一致数据就会被丢弃。4.2 使用on和ignoring指定匹配标签on(label)只使用指定的标签进行匹配。promql# 只在 instance 和 job 标签匹配时相加 node_memory_MemFree_bytes on(instance, job) node_memory_Cached_bytesignoring(label)忽略指定的标签用剩余标签匹配。promql# 忽略 instance 和 job 标签进行匹配 node_memory_MemFree_bytes ignoring(instance, job) node_memory_Cached_bytes4.3 多对一/一对多匹配group_left和group_right当左边一个元素匹配右边多个元素或反过来时需要使用group_left或group_right明确匹配关系。promql# 每个实例的 CPU 使用率除以该实例的 CPU 核心数 rate(node_cpu_seconds_total[5m]) / on(instance, job) group_left(node) node_cpu_countgroup_left表示右边的多个元素匹配左边的一个元素结果保留左边的所有标签。五、常用内置函数PromQL 提供了大量内置函数下面介绍最常用的几个。5.1 速率计算函数Counter 专用Counter 类型指标只增不减直接用值没有意义需要用函数计算变化速率。函数含义适用场景rate(v[5m])区间内的平均每秒增长率QPS、流量趋势平滑稳定irate(v[5m])区间内最后两个点的瞬时增长率突发流量检测更灵敏increase(v[1h])区间内的总增长量统计一段时间内的总请求数promql# 过去5分钟的平均 QPS rate(http_requests_total[5m]) # 捕捉瞬时突发流量 irate(http_requests_total[5m]) # 过去1小时的 500 错误总数 increase(http_requests_total{status500}[1h])5.2 变化检测函数Gauge 专用函数含义delta(v[10m])区间内起始值到结束值的变化量idelta(v[1m])区间内最后两个点的变化量promql# 过去10分钟内存变化量 delta(node_memory_MemFree_bytes[10m]) # 最近一分钟网络流量变化 idelta(node_network_receive_bytes_total[1m])5.3 数学函数函数含义abs(v)绝对值ceil(v)向上取整floor(v)向下取整round(v)四舍五入sqrt(v)平方根promql# 磁盘已用空间绝对值 abs(node_filesystem_avail_bytes - node_filesystem_size_bytes) # 内存使用量MB向下取整 floor(node_memory_MemFree_bytes / 1024 / 1024)5.4 分位数函数histogram_quantile(φ, v)用于从 Histogram 类型指标计算分位数promql# 过去5分钟 API 请求的 95 分位延迟 histogram_quantile(0.95, sum(rate(api_request_duration_seconds_bucket[5m])) by (le))5.5 标签处理函数函数含义label_join(v, dst, sep, src...)将多个标签值合并成一个新标签label_replace(v, dst, regex, src)用正则从源标签提取内容到目标标签promql# 将 instance 和 job 合并为 service 标签 label_join(http_requests_total, service, -, job, instance) # 从 instance192.168.1.1:9100 提取 IP 到 host 标签 label_replace(node_cpu_seconds_total, host, $1, instance, (.*):.*)六、结合 Grafana 可视化学习了 PromQL最终还是要落到可视化上。Grafana 是 Prometheus 最常用的可视化搭档。6.1 在 Grafana 中使用 PromQL第一步确保 Grafana 已添加 Prometheus 数据源。第二步创建 Dashboard → 添加 Panel → 在查询编辑器中输入 PromQL。第三步选择图表类型Time series、Stat、Table 等。Grafana 的查询编辑器支持两种模式Builder 模式通过下拉菜单选择指标和标签适合初学者Code 模式直接编写 PromQL支持自动补全和高亮6.2 常用可视化场景与 PromQL可视化需求PromQL 示例CPU 使用率100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance) * 100)内存使用率(1 - node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100QPS 趋势sum(rate(http_requests_total[5m])) by (job)服务可用性avg(up) by (job) * 100TOP 5 请求量topk(5, sum(rate(http_requests_total[5m])) by (endpoint))错误率sum(rate(http_requests_total{status~5..}[5m])) / sum(rate(http_requests_total[5m]))6.3 Grafana 面板配置小技巧变量使用在 Dashboard 设置中定义变量如$instance、$job查询时动态替换promqlnode_cpu_seconds_total{instance$instance}Legend 格式化用{{标签名}}让图例更清晰text{{instance}} - {{mode}}告警配置在 Panel 的 Alert 选项卡中基于 PromQL 配置告警阈值七、总结本文系统介绍了 PromQL 的核心知识体系模块核心要点基本概念瞬时向量快照、区间向量录像、标量数字二元运算符算术-*/、比较、逻辑andor聚合操作sum、avg、max、topk等配合by/without分组向量匹配默认一对一匹配用on/ignoring指定匹配标签内置函数rate速率、increase增量、histogram_quantile分位数等Grafana 集成查询编辑器输入 PromQL选择图表类型即可可视化学习建议先学会看在 Prometheus UIhttp://IP:9090/graph中尝试简单查询多用rateCounter 类型指标一定要用rate或increase才有意义注意分组聚合时想想需不需要by否则所有数据会合并成一个值善用 Grafana在 Grafana 中边写查询边看图表学习效率最高一句话总结PromQL 是 Prometheus 监控体系的核心语言——掌握了它你就能从海量监控数据中任意提取、聚合和分析让数据真正为你所用。