资讯动态

PromQL 快速上手

发布时间:2026/8/15 15:31:26 来源:尧图企业网站定制
文章目录1.简介2.主要特点3.基本用法4.Prometheus 核心概念4.1 时间序列4.1.1 样本4.1.2 指标4.2 指标类型4.2.1 计数器4.2.2 仪表盘4.2.3 直方图4.2.4 摘要4.3 底层数据结构5.数据类型6.常用函数聚合运算符速率与增量 (Rate and Derivatives)计数器处理 (Counter Resets)时间操作 (Time and Date)标签操作 (Label Manipulation)数学运算 (Mathematical Functions)逻辑与过滤 (Logical and Filtering)特殊函数排序 (Sorting)7.特殊运算符7.1 向量匹配运算符一对一/多对一7.2 集合运算符筛选向量7.3 聚合修饰符7.4 二元运算符的 bool 修饰符7.5 偏移查询 offset7.6 特殊字符运算符7.7 子查询Subquery7.8 时间戳操作符Prometheus 2.307.9 小结参考文献1.简介PromQL 是 Prometheus 监控系统的查询语言语法简洁且功能强大。PromQL 语法跟一般的 SQL 语言很不一样初学者往往需要花费几个小时阅读 官方 PromQL 文档 才能理解它的工作原理。这里请跟随我们的思路一起快速理解 PromQL 的设计精髓并掌握 PromQL 的用法。2.主要特点功能性查询语言PromQL 提供了一种功能性查询语言允许用户以一种声明式的方式来描述他们想要的数据而不是以过程式的方式来一步一步地操作。丰富的功能PromQL 支持各种运算符、函数和聚合函数可以实现复杂的查询和计算逻辑。广泛应用PromQL 被广泛应用于 Prometheus 监控系统中用于数据查询、可视化、告警等场景。3.基本用法PromQL 查询的基本语法是[selector] [modifier]selector 用于选择时间序列如http_requests_total或http_requests_total{jobmy-web-app}。modifier 用于对选择的时间序列进行操作例如聚合、过滤、计算等。PromQL 的一些常见用法查询特定指标查询某个指标例如http_requests_total过滤指标过滤掉特定标签的指标例如http_requests_total{status_code200}聚合指标对指标进行聚合例如sum(http_requests_total)或avg(node_cpu_seconds_total{modeidle})计算指标对指标进行计算例如sum(rate(http_requests_total[5m]))告警规则在 PromQL 表达式中定义警报规则当表达式结果满足一定条件时触发告警。4.Prometheus 核心概念4.1 时间序列时间序列Time Series 是 Prometheus 监控数据的核心存储单元由指标名称Metric Name和标签Labels唯一标识的、按时间顺序记录的数据点集合。通过 Node Exporter 暴露的 HTTP 服务Prometheus 可以采集到当前主机所有监控指标的样本数据。例如# HELP node_cpu Seconds the cpus spent in each mode.# TYPE node_cpu counter node_cpu{cpucpu0,modeidle}362812.7890625# HELP node_load1 1m load average.# TYPE node_load1 gauge node_load13.0703125其中非 # 开头的每一行表示当前 Node Exporter 采集到的一个监控样本node_cpu 和 node_load1 表明了当前指标的名称、大括号中的标签则反映了当前样本的一些特征和维度浮点数则是该监控样本的具体值。4.1.1 样本Prometheus 会将所有采集到的样本数据以时间序列的方式保存在内存数据库并且定时保存到磁盘。时间序列按照时间戳顺序存放我们称之为向量Vector。每条时间序列通过指标名称和一组标签集命名。时间序列每一条记录称为一个样本sample样本由以下三部分组成指标由 metric name 和描述当前样本特征的 label set时间戳一个精确到毫秒的时间戳样本值 一个 float64 浮点型数据表示当前样本值。--------------- metric ----------------------timestamp --value- http_request_total{status200, methodGET}1434417560938 94355 http_request_total{status200, methodGET}1434417561287 94334 http_request_total{status404, methodGET}1434417560938 38473 http_request_total{status404, methodGET}1434417561287 38544 http_request_total{status200, methodPOST}1434417560938 4748 http_request_total{status200, methodPOST}1434417561287 47854.1.2 指标在形式上所有指标都通过如下格式表示metric name{label namelabel value, ...}指标名称可以反映被监控样本的含义如http_request_total表示当前系统接收到的 HTTP 请求总量。指标名称只能由 ASCII 字符、数字、下划线以及冒号组成并必须符合正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*。标签反映了当前样本的特征维度通过这些维度 Prometheus 可以对样本数据进行过滤聚合等。标签的名称只能由 ASCII 字符、数字以及下划线组成并满足正则表达式[a-zA-Z_][a-zA-Z0-9_]*。其中以__作为前缀的标签是系统保留的关键字只能在系统内部使用。标签的值则可以包含任何Unicode 编码的字符。Prometheus 底层实现中指标名称实际上以__name__metric name的形式保存在数据库中因此以下两种方式均表示的同一条序列api_http_requests_total{methodPOST, handler/messages}等同于{__name__api_http_requests_totalmethodPOST, handler/messages}在 Prometheus 源码中也可以找到指标对应的数据结构如下所示typeMetric LabelSettypeLabelSetmap[LabelName]LabelValuetypeLabelNamestringtypeLabelValuestring4.2 指标类型Prometheus 主要定义了四种核心指标类型Metric Types理解这些类型对于正确查询和聚合数据至关重要。在 Exporter 返回的样本数据中其注释中也包含了该样本的类型。例如# HELP node_cpu Seconds the cpus spent in each mode. # TYPE node_cpu counter node_cpu{cpucpu0,modeidle} 362812.7890625第二行注释# TYPE node_cpu counter表明这是一个 Counter计数器类型的指标。4.2.1 计数器计数器Counter跟踪只能增加的累计值。它们通常用于跟踪处理的请求、错误和传输的字节数等。计数器指标只增不减除非系统发生重置。常见的监控指标如 http_requests_totalnode_cpu 都是 Counter 类型的监控指标。 一般在定义 Counter 指标名称时推荐使用_total作为后缀。Counter 是一个简单但强大的工具例如我们可以在应用程序中记录某些事件发生的次数通过以时序的形式存储这些数据我们可以轻松的了解该事件产生速率的变化。 PromQL 内置的聚合操作和函数可以让用户对这些数据进行进一步的分析例如通过rate()函数获取 HTTP 请求量的增长率rate(http_requests_total[5m])查询当前系统中访问量前 10 的 HTTP 地址topk(10, http_requests_total)4.2.2 仪表盘仪表盘Gauge代表一个瞬时的、可升可降的测量值通常用于跟踪内存用量、CPU 用量和磁盘可用空间等。通过 Gauge 指标用户可以直接查看系统当前空闲的内存大小node_memory_MemFree对于 Gauge 类型的监控指标通过 PromQL 内置函数delta()可以获取样本在一段时间返回内的变化情况。例如计算 CPU 温度在两个小时内的差异delta(cpu_temp_celsius{hostzeus}[2h])还可以使用 deriv() 计算样本的线性回归模型甚至是直接使用 predict_linear() 对数据的变化趋势进行预测。例如预测系统磁盘空间在4个小时之后的剩余情况predict_linear(node_filesystem_free{jobnode}[1h], 4 * 3600)4.2.3 直方图直方图Histogram跟踪值的分布情况通常用于跟踪请求延迟时间和响应大小等。在大多数情况下人们都倾向于使用某些量化指标的平均值例如CPU的平均使用率、页面的平均响应时间。这种方式的问题很明显以系统API调用的平均响应时间为例如果大多数API请求都维持在100ms的响应时间范围内而个别请求的响应时间需要5s那么就会导致某些 Web 页面的响应时间落到中位数的情况而这种现象被称为长尾问题。为了区分是平均的慢还是长尾的慢最简单的方式就是按照请求延迟的范围进行分组。例如统计延迟在0~10ms之间的请求数有多少而10~20ms之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram 和 Summary 都是为了能够解决这样问题通过 Histogram 和 Summary 类型的监控指标我们可以快速了解监控样本的分布情况。在 Prometheus Server 自身返回的样本数据中我们可以找到 Histogram 类型的监控指标prometheus_tsdb_compaction_chunk_range_bucket。# HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction # TYPE prometheus_tsdb_compaction_chunk_range histogram prometheus_tsdb_compaction_chunk_range_bucket{le100} 0 prometheus_tsdb_compaction_chunk_range_bucket{le400} 0 prometheus_tsdb_compaction_chunk_range_bucket{le1600} 0 prometheus_tsdb_compaction_chunk_range_bucket{le6400} 0 prometheus_tsdb_compaction_chunk_range_bucket{le25600} 0 prometheus_tsdb_compaction_chunk_range_bucket{le102400} 0 prometheus_tsdb_compaction_chunk_range_bucket{le409600} 0 prometheus_tsdb_compaction_chunk_range_bucket{le1.6384e06} 260 prometheus_tsdb_compaction_chunk_range_bucket{le6.5536e06} 780 prometheus_tsdb_compaction_chunk_range_bucket{le2.62144e07} 780 prometheus_tsdb_compaction_chunk_range_bucket{leInf} 780 prometheus_tsdb_compaction_chunk_range_sum 1.1540798e09 prometheus_tsdb_compaction_chunk_range_count 780对于 Histogram 类型的指标我们还可以通过histogram_quantile()函数计算出其值的分位数。比如获取最近 5 分钟 P99 请求耗时histogram_quantile(0.99,sum(rate(http_request_duration_seconds_bucket[5m]))by(le)4.2.4 摘要摘要Summary与直方图类似都是用于监控指标分布的核心工具尤其在观测延迟、响应大小等连续数值时至关重要。例如指标 prometheus_tsdb_wal_fsync_duration_seconds 的指标类型为 Summary。 它记录了Prometheus Server 中 wal_fsync 处理的耗时通过访问 Prometheus Server 的/metrics地址可以获取到以下监控样本数据# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary prometheus_tsdb_wal_fsync_duration_seconds{quantile0.5}0.012352463prometheus_tsdb_wal_fsync_duration_seconds{quantile0.9}0.014458005prometheus_tsdb_wal_fsync_duration_seconds{quantile0.99}0.017316173prometheus_tsdb_wal_fsync_duration_seconds_sum2.888716127000002prometheus_tsdb_wal_fsync_duration_seconds_count216从上面的样本中可以得知当前Prometheus Server进行wal_fsync操作的总次数为216次耗时2.888716127000002s。其中中位数quantile0.5的耗时为0.0123524639分位数quantile0.9的耗时为0.014458005s。不同在于 Histogram 通过histogram_quantile函数是在服务器端计算的分位数。 而 Sumamry 的分位数则是直接在客户端计算完成。因此对于分位数的计算而言Summary 在通过 PromQL 进行查询时有更好的性能表现而 Histogram 则会消耗更多资源。反之对于客户端而言 Histogram 消耗的资源更少。选择建议在绝大多数情况下优先选择 Histogram因为其灵活性和可聚合性在现代分布式系统中更具优势。4.3 底层数据结构Counter 和 Gauge最基础的原子单位。从存储层面来看所有指标类型最终都以 时间序列Time Series 的形式存在。Counter 和 Gauge 是最底层的“原子”样本每个时间序列仅包含一个 float64 类型的值和一个时间戳。Counter一个随时间单调递增的累计量只能增加或重启归零。Gauge一个可以任意上下波动的数值用于反映当前瞬时状态。这两个类型的数据结构在Prometheus服务端看来几乎是相同的它们的区别主要体现在语义和客户端API的设计上。Classic Histogram一个由多个 Counter 组成的“战队”。Histogram 的底层结构相对复杂其经典模型Classic Histogram 被存储为一组不同的 Counter 时间序列。以一个名为 foo 的 Histogram 为例它的底层实际上由多个独立的系列组成foo_bucket{le上边界}一系列累积计数器每个代表观测值落在该桶中的累计次数。 foo_sum一个 Counter存储所有观测值的总和。 foo_count一个 Counter存储观测的总次数与 foo_bucket{leInf} 的值相同。这种设计的缺点是这些组件作为独立的时序数据在通过网络传输时可能不完整破坏了数据的“原子性”。Native Histogram一个原子复合样本。原生直方图Native Histogram 是 Prometheus 的现代化存储方式。它不再是多个独立的时序而是将桶、总和、计数等所有数据打包成一个单一的“复合样本” 进行存储和传输。这解决了经典模型原子性问题大幅提升了存储和传输效率也无需手动配置复杂的桶边界更利于聚合。SummaryCounter 与客户端计算分位数的结合。Summary 的底层数据结构也可看作一种组合。它同样包含 _sum 和 _count 这两个 Counter但它的分位数Quantile是在客户端计算好然后直接作为一组带有 quantile 标签的时间序列暴露出来。这意味着 Summary 的分位数值不是一个基础类型而是一个包含具体数值的 Gauge。5.数据类型类型表示形式特点典型应用瞬时向量metric_name{label“value”}某一特定时间点的所有时间序列值的集合当前状态查询范围向量metric_name[5m]某时间段内的时间序列值集合变化率计算标量纯数字 3.14单一数值阈值判断/数学运算字符串“error message”文本信息注解/元数据其中向量Vector 是 Prometheus 最核心的数据结构它是时间序列数据在查询时的表现形式。Prometheus 底层按如下结构存储时间序列数据结构模型// 简化的时间序列结构typeTimeSeriesstruct{Metricstring// 如 http_requests_totalLabelsmap[string]string// 如 {method:GET, path:/api}Samples[]Sample// 数据点数组}typeSamplestruct{Timestampint64// Unix毫秒时间戳Valuefloat64// 测量值}示例数据点{metric:http_requests_total,labels:{method:GET,path:/api,status:200},samples:[{timestamp:1690000000000,value:120},{timestamp:1690000015000,value:145},{timestamp:1690000030000,value:163}]}6.常用函数PromQL 提供了丰富的函数来处理和分析时间序列数据。聚合运算符Prometheus 还提供了聚合操作符Aggregation Operators这些操作符作用于瞬时向量。可以将瞬时表达式返回的样本数据进行聚合形成一个新的时间序列。目前支持的聚合函数有sum (求和)min (最小值)max (最大值)avg (平均值)stddev (标准差)stdvar (标准方差)count (计数)count_values (对value进行计数)bottomk (后n条时序)topk (前n条时序)quantile (分位数)速率与增量 (Rate and Derivatives)计算时间序列的变化率rate(range_vector)计算区间内每秒平均增长率自动处理计数器重置。适用于单调递增的计数器如请求数。irate(range_vector)计算区间内最后两个点的瞬时增长率更敏感适合快速变化。increase(range_vector)计算区间内的绝对增长量自动处理重置。delta(range_vector)计算区间内样本值的差值可正可负适用于非计数器如温度。计数器处理 (Counter Resets)处理计数器的重置归零问题resets(range_vector)返回区间内计数器重置的次数。示例// 1小时内CPU时间重置次数 resets(process_cpu_seconds_total[1h])时间操作 (Time and Date)time()返回当前Unix时间戳秒。year(timestamp_vector)返回年份。month/day/hour/minute/second(timestamp_vector)返回时间成分值。标签操作 (Label Manipulation)修改时间序列的标签// 基于正则替换标签值。 label_replace(vector, dst_label, replacement, src_label, regex) // 将多个标签值连接为新标签。 label_join(vector, dst_label, separator, src_label1, src_label2, ...)示例从 instance“1.2.3.4:9100” 提取主机名到新标签 host“1.2.3.4”。label_replace(up{jobnode}, host, $1, instance, (.*):\d)数学运算 (Mathematical Functions)// 绝对值 abs(vector) // 四舍五入 round(vector, scalar) // 向上/向下取整。 - ceil/floor(vector) // 对数计算。 - ln/log2/log10(vector) // 指数/幂运算。 - exp/pow(vector, scalar)示例// 内存使用量保留两位小数 round(avg_over_time(memory_usage[5m]), 0.01)逻辑与过滤 (Logical and Filtering)absent(vector)检测序列是否不存在常用于告警。absent_over_time(range_vector)检测时间段内是否无数据。clamp_max/clamp_min(vector, scalar)限制值的上下限。示例// 若MySQL实例消失则触发 absent(up{jobmysql} 1)特殊函数histogram_quantile(φ, vector)直方图分位数计算根据 _bucket 和 _sum 计算分位数如 P99。// 计算 P99 请求延迟histogram_quantile(0.99,sum(rate(http_request_duration_seconds_bucket[5m]))by(le))predict_linear(range_vector, scalar)基于线性回归预测未来值如磁盘占满时间。排序 (Sorting)sort(vector) 升序排列。sort_desc(vector) 降序排列。示例// 内存使用量最高的3个序列升序显示sort(topk(3,memory_usage))7.特殊运算符PromQLPrometheus Query Language中的特殊运算符主要涉及向量匹配、集合操作、聚合修饰符等高级功能。7.1 向量匹配运算符一对一/多对一用于解决多向量间的标签匹配问题。运算符作用示例on()指定匹配的标签列# 计算各服务serviceHTTP 请求成功率sum(rate(http_requests_total{code“200”})) by (service) / on(service) sum(rate(http_requests_total)) by (service)ignoring()忽略指定标签进行匹配node_memory_free / ignoring(mountpoint) node_memory_totalgroup_left多对一匹配结果保留左向量标签requests_per_second * on(instance) group_left(cpu) cpu_usagegroup_right一对多匹配结果保留右向量标签cpu_usage * on(instance) group_right(device) disk_io7.2 集合运算符筛选向量对瞬时向量进行集合操作结果基于标签集合并集。运算符作用示例and交集保留左向量值up{job“api”} 1 and rate(errors[5m]) 0or并集保留所有值up{env“prod”} or up{env“staging”}unless差集左向量中排除右向量存在的标签disk_free unless disk_readonly7.3 聚合修饰符控制聚合计算时的标签处理逻辑。修饰符作用示例by()按指定标签分组聚合sum by (cluster, env) (http_requests_total)without ()排除指定标签后聚合avg without (pod) (container_cpu_usage)avg_over_time()跨时间区间聚合需嵌套avg_over_time(metric[1h])7.4 二元运算符的 bool 修饰符强制返回 0/1 布尔值而非筛选数据。# 比较错误率是否5%返回1(真)/0(假)(rate(errors_total[5m])/rate(requests_total[5m]))bool0.057.5 偏移查询 offset相对当前时间向前偏移查询非时间窗口移动。# 对比当前和24小时前的内存使用 node_memory_used/offset 24h注意offset 必须紧跟在选择器后不可用于函数内。# 错误写法sum_over_time(metric[1h]offset 1d)7.6 特殊字符运算符符号含义示例^指数运算2^3 → 8%取模http_requests % 10相等匹配status_code 500!不等匹配env ! “test”~正则匹配pod~“frontend-.*”!~正则不匹配job!~“backup.*”7.7 子查询Subquery嵌套时间范围查询语法function([range:[resolution]] ...)。range内部查询时间窗口如[1m]resolution结果步长如:5m表示每5分钟计算一次# 计算过去1小时内每5分钟请求率的平均值avg_over_time(rate(http_requests_total[1m])[1h:5m])7.8时间戳操作符Prometheus 2.30精确查询历史时间点数据http_requests_total 1654012800 # 查询UTC时间2022-05-31 00:00:00 http_requests_total start() # 查询区间开始时间7.9 小结关于运算符的使用需要注意以下事项向量匹配维度不一致 → 用ignoring()/on()显式声明。and 误用于布尔判断 → 需要布尔结果时用 bool 0。offset 在聚合内无效 → 改为外层偏移sum(metric) offset 1h。正则性能损耗 → 避免全量匹配~.*。参考文献官方 PromQL 文档Prometheus 和 PromQL 是什么初识PromQL - prometheus-book - GitBook

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价