当前位置: 首页 > news >正文

Prometheus(三)—— PromQL从入门到精通:掌握Prometheus数据查询的核心技术

文章目录

  • 前言
  • 一、PromQL简介
    • 1.1 什么是PromQL
    • 1.2 PromQL的核心作用
  • 二、Prometheus数据模型
    • 2.1 数据模型的核心构成
      • 2.1.1 指标名称(Metric Name)
      • 2.1.2 标签(Label)
    • 2.2 时间序列的唯一标识规则
    • 2.3 指标名称及标签使用注意事项
  • 三、样本数据格式
    • 3.1 样本数据的组成
    • 3.2 样本数据示例解析
  • 四、PromQL的数据类型
    • 4.1 即时向量(Instant Vector)
    • 4.2 区间向量(Range Vector)
    • 4.3 标量数据(Scalar)
    • 4.4 字符串(String)
  • 五、时间序列选择器
    • 5.1 选择器的作用与分类
    • 5.2 即时向量选择器
      • 5.2.1 选择器的组成
      • 5.2.2 三种常见组合方式
      • 5.2.3 标签匹配器(4种操作符)
      • 5.2.4 注意事项
    • 5.3 区间向量选择器
      • 5.3.1 定义与语法
      • 5.3.2 时间单位说明
      • 5.3.3 示例解析
  • 六、偏移向量选择器
    • 6.1 偏移选择器的作用
    • 6.2 语法与示例
      • 6.2.1 即时向量+偏移
      • 6.2.2 区间向量+偏移
    • 6.3 向量表达式使用要点
  • 七、PromQL的指标类型
    • 7.1 Counter(计数器)
      • 7.1.1 定义与特性
      • 7.1.2 常用函数与示例
    • 7.2 Gauge(仪表盘)
      • 7.2.1 定义与特性
      • 7.2.2 常用函数与示例
    • 7.3 Histogram(累积直方图)
      • 7.3.1 定义与核心特性
      • 7.3.2 生成的时间序列
      • 7.3.3 示例解析
      • 7.3.4 分位数计算(histogram_quantile)
    • 7.4 Summary(摘要)
      • 7.4.1 定义与特性
      • 7.4.2 生成的时间序列
      • 7.4.3 示例解析
      • 7.4.4 Histogram与Summary的异同
  • 八、Prometheus的聚合函数
    • 8.1 聚合函数的作用
    • 8.2 内置11种聚合函数详解
    • 8.3 聚合函数的使用场景
  • 九、PromQL的聚合表达式
    • 9.1 聚合表达式的语法格式
    • 9.2 by与without子句的区别
    • 9.3 聚合表达式实战示例
      • 9.3.1 示例1:每台主机CPU最近5分钟的平均使用率
      • 9.3.2 示例2:查询1分钟负载(load1)是否超过CPU核心数的2倍
      • 9.3.3 示例3:计算主机内存使用率
      • 9.3.4 示例4:统计所有node节点的容器总计内存(单位:GB)
      • 9.3.5 示例5:计算node01节点最近1分钟所有容器的CPU使用率
      • 9.3.6 示例6:计算最近5分钟每个容器的CPU使用变化率
      • 9.3.7 示例7:查询K8S集群最近1分钟每个Pod的CPU使用变化率
  • 总结

前言

在监控领域,Prometheus凭借其灵活的时序数据存储、强大的指标采集能力,成为云原生时代最主流的监控系统之一。而要充分发挥Prometheus的价值,PromQL(Prometheus Query Language) 作为其内置的数据查询语言,是绕不开的核心技能。无论是实时查看系统指标、生成可视化图表,还是配置告警规则、分析性能瓶颈,都需要通过PromQL实现。

本文将从PromQL的基础概念出发,逐步深入数据模型、选择器、指标类型、聚合函数等核心模块,结合实战示例解析关键用法,帮助读者系统掌握PromQL的使用技巧,真正将Prometheus的监控能力落地到实际业务场景中。

一、PromQL简介

1.1 什么是PromQL

PromQL(Prometheus Query Language)是Prometheus专为时序数据设计的查询语言,支持实时数据查询、聚合计算、多维度过滤等操作。它的核心目标是让用户能够从Prometheus存储的时序数据中,快速提取出有价值的信息

与传统的SQL不同,PromQL针对时序数据的特性做了优化,能够轻松处理时间序列+多维度标签的数据结构,满足监控场景下的各类分析需求(如计算指标增长率、统计分位数、按维度分组聚合等)。

1.2 PromQL的核心作用

1、多维度数据过滤:基于指标名称标签,精准筛选目标时间序列(如筛选“job=prometheus”且“code=200”的HTTP请求指标);
2、实时数据计算:支持算术运算、函数计算(如rate计算增长率、delta计算差值),生成衍生指标;
3、聚合统计分析:通过sum、avg、quantile等聚合函数,实现多时间序列的汇总、均值、分位数等统计;
4、时序数据可视化与告警:为Grafana等可视化工具提供数据来源,同时作为Prometheus告警规则的核心判断条件。

二、Prometheus数据模型

Prometheus的核心是时序数据(Time Series),而数据模型则定义了时序数据的组织方式。理解这一模型是学好PromQL的基础。

2.1 数据模型的核心构成

Prometheus中,每一条时间序列由“指标名称(Metric Name)”和“标签集(Label Set)”共同标识,格式如下:

<metric_name>{<label_name>=<label_value>, ...}
  • 指标名称代表着监控目标上某类可测量属性的基本特征标识
  • 标签则是这个基本特征上再次细分的多个可测量维度

2.1.1 指标名称(Metric Name)

  • 作用:描述监控目标的“基本特征”,即“监控什么”(如HTTP请求总数、CPU空闲时间);
  • 命名规范:通常采用“业务域_指标类型_单位”的格式(如prometheus_http_requests_total,表示“Prometheus的HTTP请求总数”,total表示计数器类型);
  • 示例node_cpu_seconds_total表示“节点CPU的总占用时间(秒)”,node_memory_MemFree_bytes表示“节点空闲内存(字节)”。

2.1.2 标签(Label)

  • 作用:对指标的“维度细分”,即“从哪个角度监控”(如按实例、状态、接口区分指标);
  • 特性:键值对结构,可选配置,但合理的标签设计能极大提升查询灵活性;
  • 分类:
    1、用户自定义标签:用户在指标采集时配置(如job=prometheusinstance=localhost:9090);
    2、系统默认标签:Prometheus自动添加,不显示在/metrics页面,需在target页面鼠标悬浮到label字段查看,常见默认标签如下:
    • __address__:目标实例的地址(格式<host>:<port>,如localhost:9090);
    • __scheme__:采集指标使用的协议(httphttps);
    • __metrics_path__:采集指标的URI路径(默认/metrics);
    • __param_<name>:URL参数中名称为<name>的参数值(如__param_token=123);
    • __name__:标识指标名称的预留标签,可通过它过滤指标名称(如__name__=~".*_total"匹配所有计数器指标)。

2.2 时间序列的唯一标识规则

  • 规则1:指标名称相同,但标签不同 → 不同时间序列(如prometheus_http_requests_total{code="200"}prometheus_http_requests_total{code="302"}是两条独立时序);
  • 规则2:指标名称不同 → 不同时间序列(无论标签是否相同);
  • 规则3:标签的增删改 → 生成新时间序列(如给prometheus_http_requests_total添加handler="/metrics"标签,会创建一条新时序)。

2.3 指标名称及标签使用注意事项

1、保持标签稳定性:频繁增删改标签会导致时序数据“碎片化”,不仅增加存储压力,还会使基于旧标签的图表、告警规则失效;
2、避免空标签值滥用:标签值为空时,未定义该标签的时序也会被匹配(如prometheus_http_requests_total{handler=""}会匹配所有未设置handler标签的该指标时序);
3、标签命名规范:建议使用小写字母、数字、下划线,避免特殊字符,确保可读性和兼容性。

三、样本数据格式

时间序列的本质是按时间排序的样本集合,而每个样本则是PromQL查询的最小数据单元。

3.1 样本数据的组成

每个样本包含两部分:
1、时间戳:毫秒级精度(格式为Unix时间戳,如1434317560885表示对应时间点);
2、样本值float64格式的数值(支持整数、小数,如2835.5)。

3.2 样本数据示例解析

以下是prometheus_http_requests_total指标的一组样本数据,我们标注各部分含义以帮助理解:

prometheus_http_requests_total{code="200", handler="/targets", instance="localhost:9090", job="prometheus"}  @1434317560885         28
|-------------------------- 指标名称 -------------------------| |------------------ 标签 ------------------|  |---- 时间戳 ----|  |-- 样本值 --|prometheus_http_requests_total{code="200", handler="/targets", instance="localhost:9090", job="prometheus"}  @1434317561483         35
prometheus_http_requests_total{code="200", handler="/targets", instance="localhost:9090", job="prometheus"}  @1434317562589         42

上述样本表示:在localhost:9090实例的prometheus任务中,访问/targets接口且返回码为200的HTTP请求,在不同时间点的累计次数分别为28、35、42。

四、PromQL的数据类型

PromQL表达式的返回值分为4种数据类型,不同类型适用于不同的场景(如绘图、告警、函数参数)。

4.1 即时向量(Instant Vector)

  • 定义:特定或全部的时间序列集合上,具有相同时间戳的一组样本值;
  • 核心特征:“同一时间点的多时序样本”,是可视化图表(如Grafana)的主要数据来源;
  • 示例prometheus_http_requests_total{code="200"} → 返回所有code=200prometheus_http_requests_total时序在“当前时间”的样本值。

4.2 区间向量(Range Vector)

  • 定义:特定或全部的时间序列集合上,在指定的同一时间范围内的所有样本值;
  • 核心特征:“时间范围内的多时序样本”,仅用于作为函数参数(如rate、irate),不能直接用于绘图;
  • 示例prometheus_http_requests_total{code="200"}[5m] → 返回所有code=200的时序在“过去5分钟”内的所有样本。

4.3 标量数据(Scalar)

  • 定义:一个单独的float64数值,无时间序列和标签信息;
  • 核心特征:“无维度的单一数值”,常用于算术运算或作为函数返回值;
  • 示例1003.14 → 直接表示一个数值;也可通过表达式生成,如count(prometheus_http_requests_total) → 返回该指标的时序数量(一个标量)。

4.4 字符串(String)

  • 定义:一个文本字符串,支持单引号或双引号包裹;
  • 核心特征:“无数值意义的文本”,主要用于标注或函数参数(如label_replace函数中的替换文本);
  • 示例"prometheus"'http_requests' → 直接表示一个字符串。

五、时间序列选择器

选择器是PromQL的“数据筛选工具”,用于从海量时序中挑选出目标数据。根据返回数据类型,分为即时向量选择器区间向量选择器

5.1 选择器的作用与分类

  • 作用:定义“筛选哪些时序”和“筛选哪个时间范围的样本”,是构建PromQL表达式的第一步;
  • 分类:
    1、即时向量选择器:筛选“特定时间点”的样本,返回即时向量;
    2、区间向量选择器:筛选“指定时间范围”的样本,返回区间向量。

5.2 即时向量选择器

5.2.1 选择器的组成

即时向量选择器由两部分组成(至少包含其一):
1、指标名称:筛选指定指标下的时序(可选);
2、标签选择器:筛选符合标签条件的时序(定义在{}中,可选)。

5.2.2 三种常见组合方式

1、仅指标名称:返回该指标下的所有时序;

  • 示例:prometheus_http_requests_total → 等同于prometheus_http_requests_total{},返回所有该指标的时序;

2、仅标签选择器:返回符合标签条件的所有时序(无论指标名称);

  • 示例:{code="200", job="prometheus"} → 返回所有code=200job=prometheus的时序;

3、指标名称+标签选择器:返回指定指标下符合标签条件的时序(最常用);

  • 示例:prometheus_http_requests_total{code="200", job="prometheus"} → 返回prometheus_http_requests_total指标中code=200job=prometheus的时序。

5.2.3 标签匹配器(4种操作符)

标签选择器通过“匹配器”定义筛选条件,支持4种操作符:

操作符作用示例
=完全相等code="200" → 筛选code为200的时序
!=不相等code!="500" → 筛选code不为500的时序
=~正则表达式匹配`handler=~"/targets
!~正则表达式不匹配instance!~"localhost:.*" → 排除instancelocalhost:开头的时序

5.2.4 注意事项

1、空标签值的匹配规则:若标签选择器的标签值为空(如handler=""),则未定义该标签的时序也会被匹配;

  • 示例:prometheus_http_requests_total{handler=""} → 包含所有未设置handler标签的该指标时序;

2、正则表达式的完全锚定:正则匹配需“完全覆盖标签值”,而非部分匹配;

  • 示例:code=~"2.." → 可匹配code=200code=201,但不能匹配code=1200(因1200超出2..的完全匹配范围);

3、非法选择器的规避:选择器必须包含“非空的指标名称”或“不会匹配空字符串的标签选择器”;

  • 错误示例:{job=""} → 标签值为空,且无指标名称,属于非法选择器;
  • 正确示例:{__name__=~".*_total"} → 通过__name__标签筛选指标名称,合法。

5.3 区间向量选择器

5.3.1 定义与语法

区间向量选择器是在“即时向量选择器”的基础上,添加“时间范围”(用[]包裹),语法如下:

<即时向量选择器>[<时间范围>]
  • 时间范围:以“当前时间”为基准,指向过去的特定时长(如[5m]表示过去5分钟)。

5.3.2 时间单位说明

支持的时间单位及含义如下,且需使用整数,可组合多个单位(按“大单位→小单位”顺序):

单位含义示例组合
ms毫秒-
s-
m分钟[1h30m](1小时30分钟)
h小时-
d天(24小时)-
w周(7天)-
y年(365天)-
  • 注意:不支持小数单位(如[1.5h]非法,需改为[1h30m])。

5.3.3 示例解析

  • 示例1:prometheus_http_requests_total{code="200"}[10m] → 返回code=200的该指标时序在“过去10分钟”内的所有样本;
  • 示例2:{job="node"}[1d] → 返回job=node的所有时序在“过去1天”内的所有样本。

六、偏移向量选择器

默认情况下,选择器以“当前时间”为基准筛选数据;而偏移选择器可调整基准时间,实现“查询历史数据”的需求。

6.1 偏移选择器的作用

  • 核心作用:将选择器的基准时间“向前偏移指定时长”,而非使用当前时间;
  • 适用场景:对比历史同期数据(如查询“昨天此时的CPU使用率”)、回溯历史异常数据。

6.2 语法与示例

偏移选择器通过offset关键字指定偏移时长,紧跟在选择器之后,语法如下:

<选择器> offset <偏移时长>

6.2.1 即时向量+偏移

  • 示例:prometheus_http_requests_total offset 5m → 查询“5分钟前”的prometheus_http_requests_total指标所有时序的样本;
  • 解析:基准时间从“当前”改为“5分钟前”,返回该时间点的即时向量。

6.2.2 区间向量+偏移

  • 示例:prometheus_http_requests_total[5m] offset 1d → 查询“1天前的5分钟内”的该指标所有时序的样本;
  • 解析:先将基准时间偏移1天(即“昨天此时”),再筛选该基准时间过去5分钟的样本,返回区间向量。

6.3 向量表达式使用要点

1、返回类型的场景限制

  • 绘图场景(如Grafana):仅支持即时向量;
  • 速率函数(如rate、irate):仅支持区间向量作为参数;

2、区间向量的使用限制:区间向量不能直接用于绘图,必须先通过函数(如rate)转换为即时向量;

  • 错误示例:直接在Grafana中使用prometheus_http_requests_total[5m] → 无法绘图;
  • 正确示例:rate(prometheus_http_requests_total[5m]) → 转换为即时向量后可绘图。

七、PromQL的指标类型

PromQL将指标分为4种类型,每种类型对应不同的业务场景,需结合特定函数使用。

7.1 Counter(计数器)

7.1.1 定义与特性

  • 定义:用于存储单调递增的指标数据(仅增不减,重启后重置为0);
  • 适用场景:统计累计类指标(如HTTP请求总数、错误次数、接口调用次数);
  • 核心特性:数值非负,仅支持递增(如prometheus_http_requests_total随请求增加而增大)。

7.1.2 常用函数与示例

Counter的“总数”通常无直接意义,需通过函数计算“变化率”或“排名”:
1、topk(n, 指标):返回指标下数值最大的前n条时序;

  • 示例:topk(3, prometheus_http_requests_total) → 返回HTTP请求总数排名前3的时序;

2、rate(指标[时间范围]):计算指标在时间范围内的“平均增长率”(适用于长期趋势分析);

  • 示例:rate(prometheus_http_requests_total[1h]) → 计算过去1小时内HTTP请求的平均每秒增长率;

3、irate(指标[时间范围]):计算指标在时间范围内的“瞬时增长率”(基于最后两个样本,适用于短期波动分析);

  • 示例:irate(prometheus_http_requests_total[5m]) → 计算过去5分钟内HTTP请求的瞬时每秒增长率。

7.2 Gauge(仪表盘)

7.2.1 定义与特性

  • 定义:用于存储可增可减的指标数据(数值可正可负,重启后重置);
  • 适用场景:统计波动类指标(如CPU使用率、内存空闲大小、磁盘使用率、温度);
  • 核心特性:数值随时间波动(如内存空闲大小会随进程占用而增减)。

7.2.2 常用函数与示例

Gauge常用于计算“差值”“预测值”或进行聚合(求和、均值):
1、delta(指标[时间范围]):计算指标在时间范围内的“首尾样本差值”;

  • 示例:delta(cpu_temp_celsius{host="node01"}[2h]) → 返回node01节点CPU温度与2小时前的差值;

2、predict_linear(指标[时间范围], t):通过线性回归预测指标在t秒后的数值;

  • 示例:predict_linear(node_filesystem_free{job="node"}[2h], 4*3600) → 基于过去2小时的空闲磁盘数据,预测4小时后的空闲磁盘大小;

3、聚合函数(sum/avg/min/max):对指标进行多时序聚合;

  • 示例:avg(node_memory_MemFree_bytes{job="node"}) → 计算所有node节点的平均空闲内存。

7.3 Histogram(累积直方图)

7.3.1 定义与核心特性

  • 定义:Histogram 会在一段时间范围内对数据进行采样(通常是请求持续时长或响应大小等),并将其计入可配置的 bucket(存储桶)中 ,后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。;
  • 适用场景:分析数据分布(如HTTP响应时间、请求大小),解决“长尾问题”(如大部分请求快,但个别请求极慢导致平均值失真);
  • 核心特性:采用“累积区间机制”(每个bucket包含前面所有bucket的样本)。

7.3.2 生成的时间序列

Histogram指标会以<basename>为前缀,生成3类时序:
1、<basename>_sum:所有样本值的总和;
2、<basename>_count:样本总数(本质是Counter类型);
3、<basename>_bucket{le="<上边界>"}:样本值≤上边界的样本数(le="+Inf"表示所有样本)。

7.3.3 示例解析

以“HTTP响应时间”指标prometheus_http_request_duration_seconds为例,其Histogram时序如下:

# 响应时间≤0.005秒的样本数:10
prometheus_http_request_duration_seconds_bucket{handler="/metrics",le="0.005"} 10
# 响应时间≤0.01秒的样本数:15(包含前10个样本)
prometheus_http_request_duration_seconds_bucket{handler="/metrics",le="0.01"} 15
# 响应时间≤5.0秒的样本数:20
prometheus_http_request_duration_seconds_bucket{handler="/metrics",le="5.0"} 20
# 所有样本的总响应时间:10.107670803秒
prometheus_http_request_duration_seconds_sum{handler="/metrics"} 10.107670803000001
# 样本总数:20(与le="+Inf"的bucket值一致)
prometheus_http_request_duration_seconds_count{handler="/metrics"} 20

7.3.4 分位数计算(histogram_quantile)

通过histogram_quantile(分位数, bucket指标)函数,可基于Histogram计算分位数(即“某比例的样本落在该值以下”):

  • 定义:分位数范围为0~1(如0.9表示90%的样本值≤该结果);
  • 示例:histogram_quantile(0.9, prometheus_http_request_duration_seconds_bucket{handler="/metrics"}) → 计算90%的HTTP请求响应时间≤多少秒;
  • 注意:函数假设每个bucket内的样本“线性分布”,结果为预估值,准确度取决于bucket划分的粒度(粒度越细,准确度越高)。

7.4 Summary(摘要)

7.4.1 定义与特性

  • 定义:与Histogram类似,用于存储“样本分布”,但分位数在“客户端计算并上报”,Prometheus Server直接抓取结果;
  • 适用场景:与Histogram一致(如响应时间分布),但更适合“客户端资源充足”的场景;
  • 核心特性:分位数在客户端预计算,Server无需再处理,减少Server压力。

7.4.2 生成的时间序列

Summary指标以<basename>为前缀,生成3类时序:
1、<basename>_sum:所有样本值的总和;
2、<basename>_count:样本总数;
3、<basename>{quantile="x"}:预计算的分位数(x为0~1的数值)。

7.4.3 示例解析

以“Prometheus的wal_fsync操作耗时”指标prometheus_tsdb_wal_fsync_duration_seconds为例:

# 50分位数(中位数):0.012352463秒
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
# 90分位数:0.014458005秒
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
# 99分位数:0.017316173秒
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
# 所有操作的总耗时:2.888716127秒
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
# 操作总数:216次
prometheus_tsdb_wal_fsync_duration_seconds_count 216

解析:该指标表示Prometheus的wal_fsync操作共执行216次,总耗时约2.89秒,其中50%的操作耗时≤0.012秒,99%的操作耗时≤0.017秒。

7.4.4 Histogram与Summary的异同

对比维度HistogramSummary
相同点1、均包含<basename>_sum<basename>_count
2、均用于分析样本分布,解决长尾问题;
1、均包含<basename>_sum<basename>_count
2、均用于分析样本分布,解决长尾问题;
不同点-分位数计算分位数在Server端基于bucket估算(需histogram_quantile函数)分位数在客户端预计算,Server直接抓取;
不同点-存储内容存储bucket的样本数(需配置bucket区间)存储预计算的分位数(无需配置区间)
不同点-准确度准确度依赖bucket粒度(粒度越细越准)准确度由客户端计算逻辑决定(通常更准)
不同点-资源消耗Server端计算分位数消耗资源客户端计算分位数消耗资源

八、Prometheus的聚合函数

聚合函数用于对“多时间序列的样本”进行统计计算,生成具有汇总意义的结果。

8.1 聚合函数的作用

  • 核心作用:将“多个时序的样本”按规则汇总为“单个或分组的样本”,实现“分组统计、全局汇总”等需求;
  • 常见场景:统计所有节点的CPU平均使用率、按实例分组统计内存使用总和、计算分位数分布等。

8.2 内置11种聚合函数详解

Prometheus内置11种聚合函数,各函数的功能与适用场景如下:

函数名功能描述示例
sum()对样本值求和sum(node_memory_MemFree_bytes) → 所有节点空闲内存总和
min()求取样本值中的最小值min(cpu_temp_celsius) → 所有节点CPU最低温度
max()求取样本值中的最大值max(node_cpu_seconds_total{mode="idle"}) → 空闲CPU时间最长的时序
avg()对样本值求平均值avg(node_load1) → 所有节点1分钟负载的平均值
count()统计分组内的时间序列数量count(prometheus_http_requests_total) → 该指标的时序总数
stddev()对样本值求标准差(反映数据波动程度)stddev(node_load5) → 所有节点5分钟负载的标准差
stdvar()对样本值求方差(标准差的平方,中间计算结果)stdvar(node_load5) → 所有节点5分钟负载的方差
topk(n, 指标)返回分组内样本值最大的前n条时序topk(2, node_memory_MemUsed_bytes) → 内存使用最大的前2个节点
bottomk(n, 指标)返回分组内样本值最小的前n条时序bottomk(2, node_memory_MemFree_bytes) → 空闲内存最小的前2个节点
quantile(x, 指标)计算分组内样本的x分位数(x∈[0,1])quantile(0.5, node_load1) → 所有节点1分钟负载的中位数
count_values("标签名", 指标)统计样本值的分布,生成“值→数量”的时序(标签名为统计结果的标签键)count_values("request_count", prometheus_http_requests_total) → 按请求数分组统计时序数量

8.3 聚合函数的使用场景

1、全局汇总:对所有时序进行统计(如sum(node_cpu_seconds_total{mode="used"}) → 所有节点CPU总使用时间);
2、分组统计:按标签分组后统计(如sum(node_memory_MemUsed_bytes) by (instance) → 按实例分组统计内存使用总和);
3、异常分析:通过分位数、标准差识别异常(如quantile(0.99, http_request_duration_seconds) → 99%的请求响应时间阈值,超过则视为异常)。

九、PromQL的聚合表达式

聚合表达式是“聚合函数+分组子句(by/without)”的组合,用于实现“按标签分组聚合”。

9.1 聚合表达式的语法格式

支持两种等价的语法格式(推荐第一种,可读性更高):
1、<聚合函数>(向量表达式) by|without (标签列表)
2、<聚合函数> by|without (标签列表) (向量表达式)

9.2 by与without子句的区别

  • by (标签列表):仅保留“标签列表中的标签”作为分组依据,其他标签被忽略;
    • 作用:显式指定分组维度,保留关键上下文(如job、instance);
    • 示例:sum(node_memory_MemUsed_bytes) by (instance, job) → 按instancejob分组,统计每组的内存使用总和;
  • without (标签列表):从结果中“删除标签列表中的标签”,剩余标签作为分组依据;
    • 作用:排除无关标签,简化结果;
    • 示例:sum(node_memory_MemUsed_bytes) without (cpu) → 排除cpu标签,按其他标签分组统计内存使用总和。

9.3 聚合表达式实战示例

以下示例覆盖服务器、容器、K8S等常见监控场景,帮助读者理解实际用法:

9.3.1 示例1:每台主机CPU最近5分钟的平均使用率

(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100
  • 解析:
    1、node_cpu_seconds_total{mode="idle"} → 筛选CPU空闲时间的指标;
    2、rate(...) → 计算过去5分钟内空闲CPU的平均增长率;
    3、avg(...) by (instance) → 按实例分组,计算每组的平均空闲增长率;
    4、1 - ... → 用1减去空闲率,得到使用率;
    5、*100 → 转换为百分比。

在这里插入图片描述

9.3.2 示例2:查询1分钟负载(load1)是否超过CPU核心数的2倍

node_load1 > on (instance) 2 * count(node_cpu_seconds_total{mode="idle"}) by (instance)
  • 解析:
    1、node_load1 → 节点1分钟负载;
    2、count(node_cpu_seconds_total{mode="idle"}) by (instance) → 按实例分组,统计CPU核心数(每个核心对应一条idle时序);
    3、2 * ... → CPU核心数的2倍;
    4、> on (instance) → 按instance标签对齐,筛选负载超过2倍核心数的实例。

9.3.3 示例3:计算主机内存使用率

(node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100
  • 解析:
    1、可用内存 = 空闲内存(MemFree)+ 缓存(Buffers + Cached);
    2、已用内存 = 总内存(MemTotal)- 可用内存;
    3、使用率 = 已用内存 / 总内存 * 100(百分比)。

在这里插入图片描述

9.3.4 示例4:统计所有node节点的容器总计内存(单位:GB)

sum by (instance) (container_memory_usage_bytes{instance=~"node*"}) / 1024 / 1024 / 1024
  • 解析:
    1、container_memory_usage_bytes{instance=~"node*"} → 筛选node节点的容器内存使用指标;
    2、sum by (instance) → 按实例分组,统计每组容器内存总和;
    3、/1024/1024/1024 → 将字节(Bytes)转换为GB。

9.3.5 示例5:计算node01节点最近1分钟所有容器的CPU使用率

sum(rate(container_cpu_usage_seconds_total{instance="node01"}[1m])) / sum(machine_cpu_cores{instance="node01"}) * 100
  • 解析:
    1、rate(container_cpu_usage_seconds_total{instance="node01"}[1m]) → 计算node01节点容器CPU的每秒增长率;
    2、sum(...) → 求和得到所有容器的总CPU使用率;
    3、sum(machine_cpu_cores{instance="node01"}) → 得到node01节点的CPU总核心数;
    4、/ ... *100 → 计算容器总CPU使用率占节点核心数的百分比。

9.3.6 示例6:计算最近5分钟每个容器的CPU使用变化率

sum(rate(container_cpu_usage_seconds_total[5m])) by (container_name)
  • 解析:
    1、rate(...) → 计算容器CPU的每秒增长率;
    2、sum(...) by (container_name) → 按容器名分组,统计每个容器的CPU总增长率。

9.3.7 示例7:查询K8S集群最近1分钟每个Pod的CPU使用变化率

sum(rate(container_cpu_usage_seconds_total{image!="", pod_name!=""}[1m])) by (pod_name)
  • 解析:
    1、container_cpu_usage_seconds_total{image!="", pod_name!=""} → 筛选有镜像和Pod名的容器(排除无关容器);
    2、rate(...) → 计算CPU每秒增长率;
    3、sum(...) by (pod_name) → 按Pod名分组,统计每个Pod的总CPU增长率(一个Pod包含多个容器,需求和)。

总结

PromQL作为Prometheus的核心查询语言,其知识点环环相扣:从“数据模型(指标+标签)”到“选择器(筛选时序)”,再到“指标类型(Counter/Gauge等)”和“聚合函数(统计分析)”,每个模块都是构建复杂查询的基础。

学习PromQL的关键在于“理解原理+多练实战”:
1、原理层面:明确时间序列的唯一标识规则、不同指标类型的适用场景、聚合函数的分组逻辑;
2、实战层面:结合Grafana可视化、Prometheus告警规则,尝试编写CPU、内存、容器、K8S等场景的查询表达式,逐步积累经验。

掌握PromQL后,你将能轻松从Prometheus的时序数据中提取有价值的信息,为系统监控、性能分析、故障排查提供有力支撑。后续可进一步深入PromQL的高级特性(如向量匹配、函数嵌套),不断提升查询能力。

http://www.dtcms.com/a/521270.html

相关文章:

  • 怎么在国外建网站建设行业网站大概需要都少钱
  • 手机网站有什么区别是什么意思网站开发所需费用支出有哪些
  • 网站空间的根目录可以以个人名义做网站么
  • 新网站推广方案系统优化有什么用
  • 外部依赖不稳定会给项目带来哪些风险
  • 【图像处理基石】多光谱图片去噪入门:从概念到Python实操
  • 国外网站 dns济南公司网站开发
  • 文档质量差会如何影响后期维护
  • 气象网站建设需求方案我想自己在网站上发文章 怎样做
  • 深圳微商城网站设计公司设计logo商标
  • 深度学习(四)——logistic回归
  • 网站建设开发上线流程建筑公司简历模板
  • 关于Sublime Text找不到 Install Package 的问题解决
  • 六枝特区建设局网站券多多是谁做的网站
  • 海南网站建设开发公众号制作模板网站
  • 『 QT 』QT控件属性全解析 (二)
  • 鸿蒙Next的AVSession Kit:重塑音视频播控的开发体验
  • 怎么做网站的一个横向列表网络营销跟做网站有什么区别
  • 全面掌握PostgreSQL关系型数据库,设置远程连接,笔记05,笔记06
  • 抚顺网站建设天津网站设计公司价格
  • 个人建站如何赚钱动易网站安装
  • Vue3 与微信小程序模板语法全面对比学习笔记
  • mysql、oracle的JDBC操作
  • 数码电子产品网站建设策划书网站建设推广价格
  • 高端网站设计价格成品网站和模板建站
  • vTaskDelete 的作用
  • 【笔记】ComfyUI KeyError: ‘tensorrt‘ 错误的完整解决方案
  • 网站下载软件wordpress修改上传文件路径
  • 加盟招商网站建设方案木卢seo教程
  • 【javaFX基础】实现图形能够根据窗口大小自动调整位置