日期: May 10, 2022
对于PromQL常见的sum/rate/topk/irate/delte/count等这些的用法不必多说,网上一抓一大把
真正让我纠结了很长时间的是关于group_left和group_right的用法,网上能找到的介绍少的可怜,官方说明有一说一我看不咋懂,所以我也试了很多,看怎么结合多个不同指标的标签,其实有点类似sql的多表查询jion on那样的
对于group_left和group_right适用的是一对多/多对一的情况
所以得确定哪边充当多的一方
示例一:
当我有两个指标
指标一
kafka_topic_partition_current_offset {partition="0", topic="mytopic"} 111
kafka_topic_partition_current_offset {partition="1", topic="mytopic"} 111
指标二
kafka_consumergroup_current_offset {consumergroup="lyp", partition="0", topic="mytopic"} 11
kafka_consumergroup_current_offset {consumergroup="lyp", partition="1", topic="mytopic"} 10
kafka_consumergroup_current_offset {consumergroup="lyp002", partition="0", topic="mytopic"} 2
kafka_consumergroup_current_offset {consumergroup="lyp002", partition="1", topic="mytopic"} 3
我的目的是求所有 Topic 当前总的offset - topic 某个消费者组的offset
那我直接指标一减去指标二可不可以呢? 不行的
因为指标二带有标签”consumergroup”,一个topic对应多个消费者组,所以指标二的数量肯定是比指标一多的,直接相减肯定报错,这种就是一对多的情况
用group_right 表示右边充当多的角色
一对多会把少的那边”扩充”到多的那边的数量,返回的数量是多的那边的数量
至于ignoring 和 on ,ignoring的是两边不一致的标签,on的是两边一致的标签,结果是一样的
语句
sum(kafka_topic_partition_current_offset) by (topic) - ignoring(consumergroup) group_right sum(kafka_consumergroup_current_offset) by (topic,consumergroup)
注意这里ignoring的是左边没有右边有的标签
结果
{topic="mytopic",consumergroup="lyp"} (111+111)-(11+10)
{topic="mytopic",consumergroup="lyp002"} (111+111)-(2+3)
示例二:
当我有两个指标
指标一
aliyun_acs_ecs_dashboard_diskusage_utilization {device="C:\\", diskname="C:\\", instanceId="abaabaaba", job="aliyun-exporter", userId="xxx"} 70
aliyun_acs_ecs_dashboard_diskusage_utilization {device="D:\\", diskname="D:\\", instanceId="abaabaaba", job="aliyun-exporter", userId="xxx"} 50
指标二
aliyun_meta_ecs_info {CreationTime="1999-02-01T00:00Z", ExpiredTime="2222-02-01T00:00Z", InstanceId="abaabaaba", InstanceName="阿巴阿巴阿巴", job="aliyun-exporter"} 1
我的目的是把aliyun_meta_ecs_info的标签InstanceName加到aliyun_acs_ecs_dashboard_diskusage_utilization 指标里,这样就可以根据服务器名称看其所有磁盘的使用率
这个是多对一的情况,并且aliyun_meta_ecs_info 指标的作用只是提供标签InstanceName方便结果显示
语句
(sum(aliyun_acs_ecs_dashboard_diskusage_utilization) by (instanceId,diskname)) + on(instanceId) group_left(InstanceName) ( 0* label_replace(aliyun_meta_ecs_info, "instanceId", "$1", "InstanceId", "(.+)"))
结果
{ diskname="C:\\",InstanceName="阿巴阿巴阿巴"} 70
{ diskname="D:\\",InstanceName="阿巴阿巴阿巴"} 50
这里需要注意指标一里instanceId是小写的,指标二里InstanceId是大写的,所以这个aliyun-exporter十分滴坑爹,这俩是不能直接对应得,需要先用label_replace把_InstanceId替换成instanceId_
又由于目的只是取_aliyun_meta_ecs_info_ 的一个标签,所以需要用0*aliyun_meta_ecs_info 目的是不影响结果
其实这里把_aliyun_meta_ecs_info_ 放前面,用group_right结果是一样的
示例三:
经过一番研究
我最终搞了一个这么惊天地泣鬼神的PromQL
(sum(kube_pod_container_resource_requests_cpu_cores{node=~"$node"}) by (node) /
sum (kube_node_status_allocatable_cpu_cores{node=~"$node"}) by (node) * 100 ) -
((sum((sum(kube_pod_status_phase{namespace="default",phase="Failed"}==1) by (pod)) *
on(pod ) group_right sum(kube_pod_container_resource_requests_cpu_cores{node=~"$node"}) by (pod,node) ) by(node) /
sum (kube_node_status_allocatable_cpu_cores{node=~"$node"}) by (node)) *100) or
sum(kube_pod_container_resource_requests_cpu_cores{node=~"$node"}) by (node) /
sum (kube_node_status_allocatable_cpu_cores{node=~"$node"}) by (node) * 100
目的是计算k8s节点的request占比,但由于节点上时不时有驱逐的pod残留也会算进去,那就不准了,所以需要对有驱逐pod 的节点进行过滤,减去已驱逐pod的request,这一长串我搞了老长时间(虽然直接删除残留的驱逐pod就没有这个问题了,但一直感觉可以在PromQL阶段解决这个问题,果然😃)