【Prometheus】PromQL数据类型以及常用的计算函数用法详解
✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生k8s,Prometheus监控,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:Prometheus监控系统零基础到进阶
景天的主页:景天科技苑
文章目录
- PromQL常用函数
- 1. Count类型常用函数
- 1、rate用于计算平均增长速率
- 2、irate用于计算瞬时的增长速率(灵敏度较高)
- 3、increase用于计算指定时间范围内样本值的增加量
- 2. Gauge类型常用函数
- 1、predict_linear(v range-vector, t, scalar):预测时间序列v在t秒后的值
- 2、delta(v range-vector):计算范围向量中每个时间序列上的 最后一个样本值 与 第一个样本值之差
- 3、changes() :计算监控时间范围内某个时间序列的数据变化的次数。
- PromQL二元运算符
- 1. 算术运算符介绍
- 2. 算术运算符实践
- 3. 比较运算符介绍
- 4. 比较运算符实践
- 5. 集合运算符介绍
- 6. 集合运算符实践
PromQL常用函数
PromQL提供了对时间序列数据的查询、聚合、计算和过滤等功能。在Prometheus中,时间序列(Time Series)是基本的数据单位,每个时间序列由指标名(metric name)和一组键值对(key-value pairs,即标签labels)唯一标识。
1. Count类型常用函数
在前面我们讲过,Counter类型的监控指标只增不减,因此其样本值应该是不断增大的。我们要一个不断增大的数也没什么意义,更多的时候,比如根据汽车的总里程数和时间,计算出汽车的时速。
因此单纯的Counter总数并没有直接作用,而是需要借助于rate、irate、increase等函数来计算样本数据的变化状况(增长率);
1、rate用于计算平均增长速率
计算公式:通过指定时间范围内的样本,使用最后一个样本的值减去第一个样本的值,而后除以这两个样本之间的间隔时长。
例如: rate(nginx_http_requests_total[1m]) ,表示要获取1分钟内,该指标上的http总请求数的平均增长速率;
2、irate用于计算瞬时的增长速率(灵敏度较高)
计算公式:通过指定时间范围内的样本最后一个样本的值减去前一个样本的值,而后除以这两个样本之间的间隔时长。
例如: irate(nginx_http_requests_total[1m]) ,表示要获取1分钟内,该指标上的http总请求数的瞬时增长速率;
3、increase用于计算指定时间范围内样本值的增加量
计算公式:通过指定时间范围内的样本最后一个样本的值减去第一个样本的值。
注意:increase可能会引用时间范围边界之前的样本值,以便于计算能覆盖到指定的整个时间范
围。
例如: increase(nginx_http_requests_total[1m]) ,表示要获取1分钟内,http请求的增量;
2. Gauge类型常用函数
Gauge类型的指标,存储的值是随着时间会变发生变化的,它常用求和、取平均值、最小值、最大值等;也会结合PromQL的 predict_linear 和 delta 函数使用;
1、predict_linear(v range-vector, t, scalar):预测时间序列v在t秒后的值
它通过线性回归的方式来预测样本数据的变化趋势;
例如: predict_linear(node_filesystem_avail_bytes[4h], 60602430) ,使用过去4小时的数据来预测接下来30天(60602430)的磁盘空间趋势。
我们先看下jingtian01根分区磁盘使用,目前可用33G
我们根据目前的使用情况,来预测未来30后根分区可用磁盘空间
predict_linear(node_filesystem_avail_bytes{instance="jingtian01:9100",mountpoint="/"}[1d],60*60*24*30)/1024/1024/1024
根据目前使用速度,30天后可用为28G
如此,我们就可以增加告警通知,当30天后磁盘不足多少时,触发告警,这样我们就有充足的时间来处理
2、delta(v range-vector):计算范围向量中每个时间序列上的 最后一个样本值 与 第一个样本值之差
其计算结果与increase函数相同;但delta 更适用于没有重置的场景,或者用来监控那些可能上升或下降的指标,例如温度、磁盘空间等。
例如: delta(cpu_temp_celsius{host=“prom01.oldxu.net”}[2h]) ,返回该服务器上的CPU温度与2小时之前的差异;
例如: delta(node_filesystem_avail_bytes[10m]) /1024 /1024 ,返回服务器上磁盘可用空间与10分钟之前的差异;
3、changes() :计算监控时间范围内某个时间序列的数据变化的次数。
它只关心变化的次数,而不关心具体变化的值是什么。
例如: changes(nginx_up[10m]) 监控Nginx服务在给定时间内变化的次数,如果停止了变化次数+1,启动了变化次数+1。
我们的程序没有重启过,所以都是0
当我们重启jingtian01上的node_exporter后,检测到状态变化两次,可以看到该值变成了2
由此可以判断某个服务是否发生了重启
PromQL二元运算符
PromQL提供了一系列二元运算符,包括算术运算(+ - * /)、⽐较运算( == <= >=)、以及集合运算( and or unless)。在PromQL中,用户可以执⾏以下
类型的运算:
1、标量与标量之间的运算
2、即时向量与标量之间的运算
3、两个即时向量之间的运算。(当涉及到两个即时向量的运算时,PromQL遵循向量匹配机制(Vector Matching),定义其运算逻辑)
1. 算术运算符介绍
在PromQL中算术运算符,是用来对指标数据执⾏基本的数学运算。支持的运算符有:+(加)、-(减)、*(乘)、/(除)、%(取模)和^(幂运算)
1、标量与标量之间进行数学运算,其最终得到的也是标量(使⽤较少)
# 标量与标量算数运算表达式
5 + 5
# 结果
scalar 10
2、即时向量与标量进行运算,例如
将 node_memory_MemTotal_bytes (节点内存总大小)的默认bytes单位转为MB
# 即时向量与标量算数运算表达式
node_memory_MemTotal_bytes/1024/1024
3、即时向量与即时向量进行运算,它们需要遵循向量的匹配逻辑,也就是向量与向量的标签必须完全匹配一致才可以进行运算,如果它们的标签不一致,则不会执行这个运算。
例如:我们想计算内存的可用百分比,计算公式为“(内存可用空间 / 内存总空间 * 100)= 内存可用百分比 ”这两个向量的标签是完全一致的,因此可以直接进行运算,否则⽆法正常进行运算,除非进行向量匹配特殊的处理。
# 即时向量与即时向量算数运算表达式
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100
2. 算术运算符实践
实例1:计算所有实例节点的ens33网卡,接收的总流量和发送的总流量之和
(以GB显示)
node_network_receive_bytes_total :节点网络接收的总大小
(以字节为单位)
node_network_transmit_bytes_total :节点网络发送的总大小
(以字节为单位)
# 表达式( 计算公式:(ens33接收的总流量 + ens33发送的总流量) /1024 / 1024 /1024 )
(node_network_receive_bytes_total{device="ens33"} + node_network_transmit_bytes_total{device="ens33"})/1024/1024/1024
实例2:计算所有实例节点的 /分区 已经使用了,多少空间(以GB显示)
node_filesystem_size_bytes :文件系统总大小(以字节为单
位)
node_filesystem_avail_bytes :文件系统可用空间(以字节为单
位)
# 表达式( 计算公式:(总空间 - 剩余空间) /1024 / 1024 /1024 )
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"})/1024/1024/1024
实例3:计算所有实例节点的 /分区 “已用空间百分比”
# 表达式( 计算公式:(总空间 - 可用的空间) / 总空间 * 100 )
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"})/ node_filesystem_size_bytes * 100
实例4:计算所有节点内存的“已用百分比”
node_memory_MemTotal_bytes :总内存大小(单位字节)
node_memory_MemAvailable_bytes :内存可用大小(单位字节)
# 表达式( 计算公式:(总内存 - 可用内存) / 总内存 * 100 )
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
3. 比较运算符介绍
在PromQL中比较运算符,是用来对指标的数据进行条件判断,一般在告警规则中定义何时应该触发告警。PromQL支持的比较运算符有如下几个:
== :等于,当两边的数值相等时为真。
!= :不等于,当两边的数值不相等时为真。
> :大于,当左边的数值大于右边时为真。
< :小于,当左边的数值小于右边时为真。
>= :大于等于,当左边的数值大于或等于右边时为真。
<= :小于等于,当左边的数值小于或等于右边时为真。
在PromQL中,使用比较运算符时,默认情况下,如果比较结果为假(即条件不满足),则相关的时间序列不会出现在结果中。
但是,如果在测试时,想要明确地看到哪些时间序列满足条件(为真)和哪些不满足(为假),
可以使用bool修饰符,这个修饰符会将所有的时间序列都显示在结果中,满足条件的序列会有一个值为1(true),不满⾜的序列会有一个值为0(false)。
1、标量与标量之间进行比较运算
#结果为false的显示0
5 == bool 6
#结果为true的显示1
2、即时向量与标量进行比较运算,例如判断服务器1分钟的负载,是否有大于0以上的节点
# 即时向量与标量进行比较表达式
node_load1 > 0
3、即时向量与即时向量进行比较运算,它们需要遵循向量的匹配逻辑,也就是向量与向量的标签必须完全匹配一致才可以进行运算,如果它们的标签不一致,则不会执行这个运算。
例如:我们可以比较“可用内存”是否大于“空闲内存”,如果满足该条件,那么会显示左侧的指标名称和指标当前的值。
node_memory_MemAvailable_bytes > node_memory_MemFree_bytes
4. 比较运算符实践
实例1:查询node_exporter这个job中,目前不存活实例有哪些(1为存活、0为不存活)。
up{job="node_exporter"} != 1
实例2:查询所有实例 “已使用内存”超过 30%
# 表达式:(计算公式:(总内存-可用内存)/ 总内存 * 100 大于 30 )
((node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100) > 30
实例3:查询所有的实例“磁盘可用空间”不足30%的实例
# 表达式:(计算公式:(可用空间 / 总磁盘空间) * 100 小于 30 )
(node_filesystem_avail_bytes / node_filesystem_size_bytes * 100) < 30
实例4:查询所有实例中ens33设备的网络带宽,每秒发送速率超过 200Mb/s的实例
#1、在两个测试的节点上安装:yum install iperf -y
#2、服务端运行并指定端口:iperf -s -p 9999
#3、客户端模拟带宽发送命令,-b指定发送大小,-t指定发送持续时长:iperf -c -p 99
99 -b 300M -t 60
iperf -c jingtian01 -p 9999 -b 300M -t 5000
#表达式(计算公式:rate(总的传输[1m]) * 8 /1024/1024) > 200) 网络速度或带宽通常
以位每秒(如 Mbps, Gbps)为单位。
因此需要将字节乘以8,能够将字节转换为位,这样可以更准
确地描述传输速率
如果不乘以8 则单位是M
B/s
1MB/s=8Mbps=8Mb/s
首先是“Mbps”,其全称为Million bits per second,意为每秒传输百万位(比特)数量的数据,而这里的bit(比特,1比特等于1个位)是表示数字信号数据的最小单位。
而Mb/s中的Mb与Mbps中的Mb意义相同,均表示百万位(比特)数据数量,所以Mbps=Mb/s。
rate(node_network_transmit_bytes_total{device="ens33"}[1m]) * 8 /1024 /1024
实例5:查询所有https的域名,检查域名证书的过期时间,将还剩不到90天的域名列出来(需要借助后面的blackbox黑盒监控,才能获取到对应的指标)
# 表达式,计算公式( (过期时间-当前时间) / 天(24*60*60) )
(probe_ssl_earliest_cert_expiry - time() ) / 86400 < 90
5. 集合运算符介绍
在Prometheus的查询语言中,集合运算符主要用到的运算符包括 and(并且)、or(或者)和 unless(排除)
例如:我们有两个关键指标:backup_duration_seconds 用于记录每次备份操作的持续时间,而 backup_success 则指示备份操作是否成功(1表示成功,0表示失败)
场景1:备份成功但时间超过9s
当备份操作成功完成(backup_success == 1),并且执行时间超过9秒(backup_duration_seconds > 9)时,我们需要发出告警通知“备份成功但备份时间过长”。
这就需要使用 and 运算符来确保只有当这两个条件都满足时,才触发告警。对应的表达式为: backup_duration_seconds > 9 and backup_success == 1
场景2:备份失败或时间超过9s
如果备份时长超过了9秒(backup_duration_seconds > 9),或者备份操作失败(backup_success == 0),则同样需要发出告警通知“备份失败或时间过长”。
在这种情况下,是用 or 运算符可以帮助我们在任一条件满足时触发告警。对应的表达式为: backup_duration_seconds > 9 or backup_success == 0
场景3:查询成功的备份,但排除耗时超过9s
查询所有成功的备份任务,同时排除那些执行时间超过9秒的任务,这样我们就可以只关注于那些成功备份的任务,并且备份效率较高的。
我们可以利用unless 运算符来实现,对应的表达式为: backup_success == 1 unless backup_duration_seconds > 9
1、and运算符示例,查询当前实例“1分钟负载大于2,并且5分钟负载小于2”,如果满足条件说明当前发了了突增的负载压力。
注意:and运算需要遵循向量的匹配逻辑,也就是向量与向量的标签必须完全匹配一致才可以进行匹配,如果它们的标签不一致,则不会执行匹配逻辑,除⾮使用ignore忽略不一致的标签来进行匹配。
# 模拟负载高命令 stress --cpu 8 --timeout 60
yum install stress -y
#由于我们压力测试只执行了60秒。所以jingtian021分钟负载⽐较高,而5分钟负载并不高
node_load1 > 2 and node_load5 < 2
2、or示例,查询 jingtian01:9100 上CPU编号为 0 的idle 时间或 user 时间
node_cpu_seconds_total{cpu="0",mode="idle"} or node_cpu_seconds_total{cpu="0",mode="user"}
3、unless示例,查询 node_cpu_seconds_total 指标上CPU编号为0的,但要排除node02和node03节点,同时还要排除模式为 idle|user|system|steal|nice
node_cpu_seconds_total{cpu="0"} unless node_cpu_seconds_total{instance=~"jingtian02:9100|jingtian03:9100"} unless node_cpu_seconds_total{mode=~"idle|user|system|steal|nice"}
6. 集合运算符实践
实例1:查询实例的网络接收流量“并且”网络发送流量,每秒传输超过 200Mb/s
#模拟接收和发送流量比较高:"需要在同一节点"模拟服务端和客户端,执行如下命令
#1、模拟服务端:iperf -s -p 9999
#2、模拟客户端:iperf -c prom-node01.oldxu.net -p 9999 -b 300M -t 60
# 表达式
rate(node_network_receive_bytes_total[1m]) *8 /1024 /1024 >200 andrate(node_network_transmit_bytes_total[1m]) *8 /1024 /1024 >200
# 结果
{device="ens33", instance="jingtian01:9100", job="node_exporter"}300.4421537611219 # 这个实例发送和接收同时达到了300Mb/s
实例2:查询当前磁盘,可用空间不足20GB“或者”当前磁盘可用空间不足30%
node_filesystem_avail_bytes /1024/1024/1024 < 20 or (node_filesystem_avail_bytes / node_filesystem_size_bytes * 100 < 30)
实例3:通过 probe_http_status_code 指标获取当前监控的网站返回的状态码,并从中筛选出小于200的状态码“或者”大于400的状态码
# 表达式
probe_http_status_code <= 199 orprobe_http_status_code >= 400