Prometheus 教程

PromQL 示例:使用内置函数、操作符

在 Prometheus 中,为了更为方便、快捷的使用 PromQL 语言查询数据,内部提供了大量的内置函数,用于聚合运算等等,同时也提供了很多运算符,如数字运算加减乘除等等。

示例一:使用 rate() 函数计算增长率

rate() 函数是 Prometheus 查询语言 (PromQL) 中的一个内置函数,用于计算时间序列数据的平均增长率。它可以帮助你了解时间序列数据的变化趋势,特别是在监控和警报方面。

rate() 函数的基本语法如下:

rate(metric_name[range_vector])

其中:

  • metric_name 是你想要计算增长率的指标名称。

  • range_vector 是一个范围向量选择器,指定了计算增长率的时间窗口。

rate() 函数会计算指标在指定时间窗口内的平均增长率。具体来说,它会取时间窗口内最后两个数据点,并计算这两个数据点之间的增长率。然后,它会将这个增长率作为整个时间窗口的平均增长率返回。

例如,如果你想要计算过去 5 分钟内 prometheus_http_requests_total 指标的平均增长率,你可以使用以下查询:

rate(prometheus_http_requests_total[5m])

这个查询会返回一个标量值,表示过去 5 分钟内 prometheus_http_requests_total 指标的平均增长率。

执行结果如下图:

PromQL 示例:使用内置函数、操作符

示例二:使用 sum() 函数求和

sum() 函数用于计算指定时间范围内的时间序列数据的总和。这个函数通常用于聚合多个时间序列数据点,以便得到一个单一的总计值。

sum() 函数的基本语法如下:

sum(metric_name[range_vector])

其中:

  • metric_name 是你想要计算总和的指标名称。

  • range_vector 是一个范围向量选择器,指定了计算总和的时间窗口。

注意:sum() 函数会将所有选定时间范围内的数据点相加,不考虑数据点的时间戳。这意味着,如果时间范围包含多个相同的时间戳(这在实际中不太可能,但理论上可能),那么这些值会被多次相加。

此外,sum() 函数通常与 by() 子句一起使用,以便按特定标签对时间序列进行分组并计算每个组的总和。例如,如果你想要计算每个作业(job)在过去一小时内的 HTTP 请求总数,你可以使用以下查询:

sum(http_requests_total{job=~"job1|job2"}[1h]) by (job)

或者

sum by (job) (http_requests_total{job=~"job1|job2"}[1h])

这个查询会返回一个按 job 标签分组的时间序列,每个时间序列表示相应作业在过去一小时内的 HTTP 请求总数。

注意:sum() 函数只能用于计数器(Counter)类型的指标,因为计数器是单调递增的,适合累加。对于其他类型的指标(如 Gauge),使用 sum() 函数可能没有意义,因为 Gauge 指标的值可以任意变化,不一定适合累加。

实例:假设 prometheus_http_requests_total 时间序列都有 job 标签,我们可能希望对所有实例的速率求和,这样就能减少输出时间序列,但仍能保留作业维度:

sum by(job) (
  rate(prometheus_http_requests_total[5m])
)

让我们逐步分析这个查询:

  • prometheus_http_requests_total[5m]:prometheus_http_requests_total 是一个计数器类型的指标,通常用于表示 Prometheus 服务器收到的 HTTP 请求总数。[5m] 是一个范围向量选择器,表示选取过去5分钟内的数据点。

  • rate(prometheus_http_requests_total[5m]):函数 rate() 计算指定时间范围向量内的指标的平均增长率。在这里,它计算了 prometheus_http_requests_total 在过去5分钟内的平均增长率。这个增长率是一个即时向量,因为它表示了在每个时间点上的增长率,而不是一个时间段内的总和。

  • sum by(job) (...):sum by(job) 表示按照 job 标签对即时向量进行分组,并计算每个组的总和。这意味着查询结果将为每个唯一的 job 标签值提供一个总和,该总和表示该作业在过去5分钟内的平均请求增长率。

综上所述,这个查询将返回每个 Prometheus 作业(由 job 标签标识)在过去5分钟内的 HTTP 请求平均增长率的总和。这个查询有助于了解不同 Prometheus 作业在给定时间范围内的请求增长率情况。如果某个作业的请求增长率异常高或低,这可能表明该作业的性能或流量模式与其他作业有所不同,需要进一步调查。

执行结果如下图:

PromQL 示例:使用内置函数、操作符

示例三:使用运算操作符

如果我们有两个具有相同维度标签的不同指标,我们可以对它们应用二元运算符,两边具有相同标签集的元素将被匹配并传播到输出中。例如(单位:MiB):

(windows_os_virtual_memory_bytes - windows_os_virtual_memory_free_bytes) / 1024 / 1024

上述表达式将计算 Windows 操作系统上已使用的虚拟内存量,并且将其从字节转换为兆字节(MB)。步操作分析如下:

  1. windows_os_virtual_memory_bytes:这个指标代表了系统的总虚拟内存大小(以字节为单位)。

  2. windows_os_virtual_memory_free_bytes:这个指标代表了系统虚拟内存中当前空闲的部分(以字节为单位)。

  3. windows_os_virtual_memory_bytes - windows_os_virtual_memory_free_bytes:通过减去空闲内存,我们得到了当前已使用的虚拟内存量(以字节为单位)。

  4. / 1024:将字节转换为千字节(KB)。

  5. / 1024:再次除以1024,将千字节转换为兆字节(MB)。

最终,这个表达式会返回一个表示已使用虚拟内存量的 Prometheus 即时向量,单位是兆字节(MB)。

运行结果如下图:

PromQL 示例:使用内置函数、操作符

同样的表达式,但通过应用求和,可以这样写:

sum by (job,instance) (
  windows_os_virtual_memory_bytes - windows_os_virtual_memory_free_bytes
) / 1024 / 1024

运行结果如下图:

PromQL 示例:使用内置函数、操作符

示例四:分组获取前 3 的数据

在 Prometheus 中,topk() 函数是一个向量聚合操作符,用于从给定的向量中选取具有最大或最小值的 k 个样本。

topk() 函数有两种形式:

  • topk(k, vector):返回向量中最大的 k 个样本。

  • bottomk(k, vector):返回向量中最小的 k 个样本。

其中,k 是一个整数,表示你想要选取的样本数量,而 vector 是你想要从中选取样本的向量。

例如,假设你有一个名为 prometheus_http_requests_total 的指标,该指标记录了过去一段时间内 HTTP 请求的总数。你可以使用 topk() 函数来找出请求量最高的前 10 个实例:

(1)先执行如下 PromQL 查看 prometheus_http_requests_total 的指标:

prometheus_http_requests_total

执行结果如下图:

PromQL 示例:使用内置函数、操作符

然后,使用 topk() 函数获取 prometheus_http_requests_total 指标中请求数最大的 10 个:

topk(10, prometheus_http_requests_total)

执行结果如下图:

PromQL 示例:使用内置函数、操作符

上图返回了一个包含 10 个样本的向量,其中每个样本都是 prometheus_http_requests_total 指标中最大的 10 个值之一。

注意:topk() 函数返回的是样本的原始值,而不是时间序列或标签。如果你需要查看与这些样本相关联的时间序列或标签,你可能需要使用其他 PromQL 函数或操作符来进一步处理结果。

如果同一个虚构集群调度程序为每个实例提供如下 CPU 使用指标:

instance_cpu_time_ns{app="lion", proc="web", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="elephant", proc="worker", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="turtle", proc="api", rev="4d3a513", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="fox", proc="widget", rev="4d3a513", env="prod", job="cluster-manager"}
...

我们可以得到按应用程序(app)和进程类型(proc)分组的前 3 个 CPU 用户,就像这样:

topk(3, sum by (app, proc) (rate(instance_cpu_time_ns[5m])))

查询语句详细分析:

  • instance_cpu_time_ns[5m]:  这部分选择了一个名为 instance_cpu_time_ns 的指标,并在过去 5 分钟的时间范围内抓取了这个指标的数据。

  • rate(instance_cpu_time_ns[5m]):  使用 rate 函数计算 instance_cpu_time_ns 指标在过去 5 分钟内的平均增长率。rate 函数通常用于计算计数器(Counter)类型指标的平均增长率,以获取一个类似速率的值。

  • sum by (app, proc):  这部分使用 sum 聚合操作符对 rate 函数的结果进行聚合,并按 app 和 proc 标签进行分组。这意味着它会计算每个 app 和 proc 组合的平均 CPU 时间增长率的总和。

  • topk(3, ...):  最后,topk 函数被用来从聚合结果中选择最大的 3 个样本。这些样本将基于 sum by (app, proc) 计算出的总和值进行排序,最大的 3 个值将被返回。

综上所述,整个查询的目的是找出在过去 5 分钟内,按 app 和 proc 分组后,CPU 时间增长率总和最高的前 3 个 app 和 proc 组合。

如果 instance_cpu_time_ns 指标包含每个运行实例的一个时间序列,则可以像这样计算每个应用程序的运行实例数:

count by (app) (instance_cpu_time_ns)

查询语句详细分析:

  • instance_cpu_time_ns:  这是一个指标选择器,它选择名为 instance_cpu_time_ns 的所有时间序列,这个指标可能表示某个实例的CPU时间。

  • count by (app):  聚合操作符 count by 根据 app 标签对 instance_cpu_time_ns 指标的所有时间序列进行分组,并计算每个 app 分组中的样本数量。

综上所述,整个查询将返回一个向量,其中的每个样本都包含一个 app 标签和对应的样本数量,表示有多少个时间序列具有相同的 app 标签值。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号