PromQL进阶与运用

2023-11-23 22:26:44 浏览数 (3)

PromQL是Prometheus内置的数据查询语言,其提供对时间序列数据丰富的查询,聚合以及逻辑运算能力的支持。并且被广泛应用在Prometheus的日常应用当中,包括对数据查询、可视化、告警处理当中。

上一篇我们从PromQL入门,这个篇章我们继续学习下PromQL的进阶知识与实际的使用

嵌套结构

    PromQL是一种用于查询和分析时间序列数据的语言,它和SQL有一些相似之处,但也有一些明显的区别。下面我们将详细介绍PromQL的嵌套结构,并给出具体的例子,同时将其与SQL进行对比。

函数嵌套

PromQL中支持函数嵌套,例如:

代码语言:javascript复制
sum(rate(http_requests_total[5m])) by (job)

这个查询中,我们使用了两个函数,rate() 和 sum()。rate()函数用于计算速率,sum()函数用于计算总和。这个查询的作用是计算最近5分钟内每个job的http请求总数。

SQL中也支持函数嵌套,例如:

代码语言:javascript复制
SELECT AVG(SUM(column)) FROM table GROUP BY column

这个查询中,我们使用了两个函数,AVG()和SUM()。AVG()函数用于计算平均值,SUM()函数用于计算总和。这个查询的作用是计算每个分组的平均值。

向量选择器嵌套

PromQL中的向量选择器用于选择指定标签的时间序列数据,并支持嵌套,例如:

代码语言:javascript复制
sum(rate(http_requests_total{job="frontend"}[5m])) by (instance)

这个查询中,我们选择了job="frontend"的时间序列数据,并使用rate()函数计算请求速率,然后使用sum()函数计算每个实例的请求总数。

SQL中的向量选择器通常是通过嵌套查询实现的,例如:

代码语言:javascript复制
SELECT COUNT(*) FROM table WHERE column IN (SELECT column FROM table2)

这个查询中,我们使用嵌套查询选择了一个列,然后使用COUNT()函数计算符合条件的行数。

操作符嵌套

PromQL中支持操作符嵌套,例如:

代码语言:javascript复制
sum(rate(http_requests_total{job="frontend"}[5m])) / sum(rate(http_requests_total[5m])) * 100
代码语言:javascript复制
这个查询中,我们使用了两个除法操作符/和一个乘法操作符*,用于计算前端请求占总请求的百分比。

SQL中也支持操作符嵌套,例如:

代码语言:javascript复制
SELECT column1 / column2 * 100 FROM table

这个查询中,我们使用了两个除法操作符/和一个乘法操作符*,用于计算一个列的值占另一个列的值的百分比。

PromQL的结果类型

    PromQL的结果类型主要有四种:标量(Scalar)、向量(Vector)、字符串(String)、以及布尔类型(Boolean)。下面我们将逐一介绍这些结果类型,并给出具体的例子。

标量(Scalar)

标量是一个单独的数值结果。标量通常用于表示聚合计算的结果,例如计算平均值或总和。标量的单位可以是任何支持的单位,例如字节、秒、毫秒等。

例如,以下PromQL查询返回当前可用内存的平均值:

代码语言:javascript复制
avg(node_memory_MemAvailable)

该查询的结果是一个标量,表示平均可用内存。

向量(Vector)

向量是一组带有标签的时间序列数据。向量通常用于表示单个指标在时间上的变化情况,例如CPU使用率或磁盘空间使用率。向量的每个时间序列数据都具有相同的标签集,每个标签都有一个唯一的名称和值。

例如,以下PromQL查询返回CPU使用率:

代码语言:javascript复制
cpu_usage{instance="webserver-01"}

该查询的结果是一个向量,其中每个时间序列表示webserver-01实例的CPU使用率。

字符串(String)

字符串是一个文本字符串结果。字符串通常用于表示元数据信息或用户友好的错误消息。

例如,以下PromQL查询返回Prometheus的版本信息:

代码语言:javascript复制
prometheus_version

该查询的结果是一个字符串,表示当前Prometheus的版本信息。

布尔类型(Boolean)

布尔类型是一个只有两个值(true或false)的结果。布尔类型通常用于表示条件表达式的结果。

例如,以下PromQL查询返回http_requests_total是否存在:

代码语言:javascript复制
http_requests_total > 0

该查询的结果是一个布尔类型,如果http_requests_total存在且其值大于0,则结果为true,否则为false。

    PromQL的结果类型非常丰富,可以满足各种不同的查询需求。了解这些结果类型可以帮助我们更好地理解PromQL的查询结果。

PromQL的运算符

PromQL的运算符包括算术运算符、比较运算符、逻辑运算符、聚合函数和函数操作符等。下面我们将逐一介绍这些运算符,并给出具体的例子。

算术运算符

算术运算符用于执行基本算术操作,例如加减乘除和取模等。PromQL支持的算术运算符如下:

代码语言:javascript复制
 :加法运算符
-:减法运算符
*:乘法运算符
/:除法运算符
%:取模运算符

例如,以下PromQL查询计算node_memory_MemAvailable和node_memory_MemTotal的差值:

代码语言:javascript复制
node_memory_MemTotal - node_memory_MemAvailable

比较运算符

比较运算符用于比较两个数值或时间戳。PromQL支持的比较运算符如下:

代码语言:javascript复制
==:等于运算符
!=:不等于运算符
<:小于运算符
>:大于运算符
<=:小于等于运算符
>=:大于等于运算符

例如,以下PromQL查询返回node_load1是否大于1:

代码语言:javascript复制
node_load1 > 1
代码语言:javascript复制
逻辑运算符

逻辑运算符用于将多个表达式组合在一起,从而形成更复杂的查询。PromQL支持的逻辑运算符如下:

代码语言:javascript复制
and:逻辑与运算符
or:逻辑或运算符
unless:逻辑否定运算符

例如,以下PromQL查询返回同时满足node_cpu_seconds_total和node_memory_MemAvailable大于0的时间序列数据:

代码语言:javascript复制
node_cpu_seconds_total and node_memory_MemAvailable > 0

聚合函数

聚合函数用于对多个时间序列数据进行聚合操作,从而生成单个时间序列数据。PromQL支持的聚合函数如下:

代码语言:javascript复制
sum (在指定维度上求和)
max (在指定维度上求最大值)用于计算所有时间序列数据的最大值,并返回一个新的时间序列数据
min (在指定维度上求最小值)
avg (在指定维度上求平均值)
stddev (在指定维度上求标准差)
stdvar (在指定维度上求方差)
count (统计向量元素的个数)
count_values (统计具有相同数值的元素数量)
bottomk (样本值中最小的 k个值)
topk (样本值中最大的 k个值)
quantile (在指定维度上统计 φ-quantile 分位数(0 ≤ φ ≤ 1))

例如,以下PromQL查询返回node_cpu_seconds_total的平均值:

代码语言:javascript复制
avg(node_cpu_seconds_total)

计算node_cpu_seconds_total时间序列数据中cpu标签值为cpu0的最大值:

代码语言:javascript复制
max(node_cpu_seconds_total{cpu="cpu0"})

函数操作符

函数操作符用于对时间序列数据进行变换操作。PromQL支持的函数操作符如下:

代码语言:javascript复制
rate:计算速率函数
irate:计算瞬时速率函数
delta:计算增量函数
abs:取绝对值函数

例如,以下PromQL查询返回node_cpu_seconds_total的速率:

代码语言:javascript复制
rate(node_cpu_seconds_total[1m])

其他函数的详细含义与使用可以看:https://hulining.gitbook.io/prometheus/prometheus/querying/functions

PromQL与监控策略的结合

告警引擎会根据用户的配置,周期性地执行查询。

监控k8s-master节点的内存可用率低于 10%的时候告警,配合for 1m 标识连续一分钟的都命中策略才告警

代码语言:javascript复制
groups:
- name: host
  rules:
  - alert: MemUtil
    expr: mem_available{app="k8s-master"} / mem_total{app="k8s-master"} * 100 < 10
    for: 1m
    labels:
      severity: error
    annotations:
      summary: Mem available less than 20%, host:{{ $labels.ident }}

Google的四个黄金指标与PromQL

请求量(Request Rate):表示单位时间内系统接收到的请求数量,通常用每秒请求数(QPS)来表示。

示例:使用rate函数来计算每秒请求量。例如,计算过去 5 分钟内的请求量

代码语言:javascript复制
rate(http_requests_total[5m])

延迟(Latency):表示系统处理请求所需的时间。延迟通常以平均延迟或百分位数来表示,例如平均延迟、90th 百分位延迟、99th 百分位延迟等。

示例:使用histogram_quantile函数来计算某个百分位数的延迟。例如,计算过去 5 分钟内的 90th 百分位延迟

代码语言:javascript复制
histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[5m]))

失败率(Error Rate):表示请求失败的比例。例如,HTTP 500 错误、超时等都可以被认为是错误。

示例:使用irate函数来计算每秒的错误数,然后除以请求总数。例如,计算过去 5 分钟内的失败率

代码语言:javascript复制
irate(http_request_duration_seconds_count{status_code="500"}[5m]) / rate(http_requests_total[5m])

饱和度(Saturation):表示系统资源使用的情况,通常以某个资源的使用率或队列长度等指标来衡量。当系统处于高负载状态时,饱和度指标将趋近于 100%。

示例:使用资源使用率或队列长度等指标来衡量系统资源的使用情况。例如,计算过去 5 分钟内 CPU 使用率的平均值

代码语言:javascript复制
avg(rate(container_cpu_usage_seconds_total{container_name!="POD"}[5m])) by (pod_name)

推荐阅读博文:https://p8s.io/docs/promql/query/aggregate/

可以查看原文:

https://mp.weixin.qq.com/s?__biz=MzA5NTgwNzY1NA==&mid=2247484027&idx=1&sn=fc3dfdb968493855f9410d72ebc2537e&chksm=90b8f3b2a7cf7aa4592c5f4978364c5a4f366781b9fc5fc5b17d3fda0520e5c23008e1a51c91&token=889147174&lang=zh_CN#rd

关注公众号获取更多sre博文:五分钟学SRE

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞