PromQL 进阶|学习笔记(三)

简介: 快速学习 PromQL 进阶

开发者学堂课程3天吃透 PrometheusPromQL 进阶学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/1244/detail/18448


PromQL 进阶


三、二元运算符

再说下一个话题,叫做二元运算符,可能会更绕,但是二元运算也是Prometheus最强大的功能之一,将来我们自己想在Grapha上绘图,自定义绘图像我们所谓的promql,如果不会写,相当于没学Prometheus而这其中,二元运算符又是让我们去表达非常高级的运算逻辑的一个非常重要的表达式,或者叫表达使用条件,或者叫使用机制。

promql支持基本的算数和逻辑运算意思是我们完全可以将两个向量表达式之类的来连接起进行逐一比较或者一对多比较,这种方式来进行比较,我们可以相当于想象成类似于比如我们在两个之间求个集合,求个交集,求个并集,求个差集,类似这种运算,这两个集合之间,因为你的每一个时间序列时候都有很多样本值对多个样本之彼此之间求交集,这其实就是一种类似的计算。当然我这样描述并不精确,要看它支持哪些运算像这种支持使用操作符连接两个操作数的,称为叫二元运算符这没有什么难理的,叫1+1,所以加法运算两个。我们以前还没有使用过其实我曾经在示例中给大家用过一次,比如谁除以谁,乘以谁,这种都叫二元运算。

我们过去的表达式给大家讲到的这些语法当中还不包含,我们来看在promql当中,二元运算符或者二元操作符所支持的运算第一,在两个标量间运算,这简单比如1+1,这就是两个标两间的运算,一对二取幂,这也是所谓叫两个标两间的运算,这叫幂运算也可以在及时向量和标量间运算,注意一个及时向量和一个标量,所以一个及时向量这里是<1、2、3>样本值,这叫及时向量,时间训练样本值,乘以2,大家应该学过,算术中应该学过,得到结果应该是<2、4、6>,得到另外一个向量。就是这种计算,它不难。这叫在小学算术中叫好像它只是一个值乘以一个多项式。我可以这么来理解。比如x加y加z,乘以2得为结果。比如2X加2Y加2Z,也可以是两个即时向量的运算。两个即时向量是这样x加y比如乘以m加n。看他们到底怎么,该怎么算,等于什么?我们正常的算法大家应该知道应该是多对多的,是多对多。x乘以m,x乘以n,再加上y乘以m,再加上y乘以n,多样式展开,其实就是多对多。左侧的每一个,对右侧的每一个这叫多对多计算。但是我也可以这样,也可以这样,只在左侧找一个,在右侧找与它相匹配的每一个,这叫一对多对。左侧x如果这里的m,我认为可能有一种判断条件,m能够跟x连接起来,那就是等于xm但是n个x连不起来,那就不算。然后再算y,y跟m进行计算像这种叫一对多,也可以是多对一。希望大家能够有个基本的逻辑。

对于我们的Prometheus而言,它们的运算是遵循向量匹配机制。不是这样直接展开,而究竟是一对多还是多对一,我们需要自己明确定义。它不支持多对多,只支持一对一,一对多,多对一三种式。而一对多,多对一其实是一个概念,是谁是1谁是多的问题。而这个概念就叫做向量匹配模式,或者叫向量匹配机制。

1. 向量匹配机制支持的运算

第一,算数运算,就是加减乘除取膜和取幂运算。这是这样6种运算符比较运算,各位应该理解等值比较,不等值比较,大于小于大于等于小于等于,这叫比较运算。而逻辑或者集合运算,跟刚才我们讲求交集,求并集,这求差集,类似于差距的概念。但是各位要注意目前逻辑集合运算仅允许在2个即时向量间进行上,不支持标量参与运算。也就是既然是集合运算,用一个单个值跟另外一个集合的运算,它是不允许的,必须是两个集合间的运算,所以只能是两个向量间的运算。这个向量叫即时向量,不能是范围向量。但是前面这两种都支持标量间运算,即时向量和标量间运算,或者两个即时两件的运算都可以。要记得这是二元运算符。

2.二元运算符优先级

如果我们在一个表达式中表达很复杂,它是如何运算的?一般来讲,它满足结合率,大家知道,我们从小学应该学过叫左结合,如果没有使用括号,比如1+2-1,就表示左结合。先算左边再算右边。当然我指的是相同优先级。对于不同优先级,我就先算优先级高的,比如1+2*3,应该先算2*3,再算一+,后边他又减6,一样的先算2*3。但是对于外层来讲,满足结合是不是我们要满足,我们要改变优先级怎么办?加括号,这时候就可以改变它的所谓的优先级。看优先级,幂是最高优先级,乘除第二优先级加减次之,比较运算再次之,逻辑运算最后。而or是最低优先级。逻辑运算and,unless。优先级可以,而or是最低优先级的。大家一定要记得。但是我们可以使用括号改变它的优先级次序。我来看向来匹配的逻辑,我再给大家举例子说明。

3.向量匹配逻辑

先来看向量匹配逻辑,向量匹配当中支持这样几种匹配机制。第一叫1对1,左侧一个在右侧只找出来一个,一定是一对一的。如果右侧或者左侧有多出怎么办?比如这边多出两个,在右边找不到匹配,而右边有个值也没有被左侧的匹配到,是不是有那种可能性?你先对这个问题先存疑就行。我这画的图只是表达一对一的意思,一对多或者多对一看底下图,一对多,多对一。一个人可以养多个宠物,一个人可以养多种多个宠物,而多个宠物也可以属于一个主人。所以这左侧是一对多,右侧是多对一,就是这意思。所以我们说他们其实没区别,只是谁是多方,谁是少方而已,或者谁是一方而已。

来看一对一匹配它的意义。看大家能不能理解。即时向量一对一匹配指的是从运算符两边表达式所获取的即时向量间,叫依次比较,并找出唯一匹配。什么叫唯一?左侧和右侧的即时向量,它们的标签是完全一致的样本值。这是即时向量,意味着什么?还记得什么叫及时向量?比如这里有n个时间序列,是这些所有时间序列的最新值。我们可以认为每一个样本值它的标签可能并不一样?第一个值,第二值的标签是不是并不一样?同样的逻辑我们还有另外一个表达是也指定了一堆时间序列的及时值。现在我们要干什么?对第一个取及时值和第二个及时向量之间找,逐一比较,找每样本值之间。注意一定是跨左右的,跨向量的找样本值之间的标签是完全一样两个,而且一定是匹配的,一定是完全一致的。找不到怎么办?不会出现在结果中,找不到的则不会出现在结果当中。一定要记住这一点。有些东西都很奇怪,我们用来干什么?这种计算你看,这是通常是用来在监控中,统计起来特别有重要

底下示例,我们先说示例或者先看表达式语法:ignoring(),on(),我们使用一个即时向量,右边一个即时向量,中间指定做什么运算,或者加减乘除之类的运算这叫二进制或者叫二元表达式或者叫二元操作符。Bin-operator,叫bin-aryoperator。后面使用ignoring()。叫定义匹配检测时要忽略的标签,意思是除标签生效匹配就行,指定的标签只要匹配就行,剩下的匹不匹配无所谓。所以跟刚才聚合运算相似,是在逻辑上看底下设定。

首先我们看示例(rate(http_requests_total{status_code=~”5*”}[5m])>.1*rate(http_ requests_total[5m])表达是什么意思?他表达是什么意思?首先, HTTP request total是一个指标.这个指标我们取的是做一个过滤。意思是如果标签的值是5开头,取出指标下所有以5开头的响应码的时间序列,这个时间序列可能不止一个。为什么我这里只给一个标签?它可能分别统计比如a、p,I、u、r、l项,5XX是多少实验序列主页之下有个实验序列5XX响应码。所以可能是有多个时间序列,一定要记得接着我们要对5分钟之内,因为它是个total值,这是个计数器,不能叫范围向量,这是个计数器,对计数器而言,说过取样本值没有意义评估。我们通常对于计数器要做什么?要做速率计算比如我们以5分钟为范围去求它的速率,这得出来是一个Delta值,就是一个上下波动的值。上下波动值对我们来讲去评估才有意义。再重复一遍,计数器对我们而言没有直接意义,多数情况下我们都要做速率运算的。至于速率运算的时候,时间根据需要来评估,这生成结果。rate不是聚合函数,rate不是聚合函数,它就是一个prometheus的函数。等会来给它解释它的函数。这个计算结果就是一个即时向量。我们把即时向量注意,这是干什么?

大于这就是二元操作符,做大于计算,则大于计算什么?又是

Rate ignore request total。没有对标签做过滤,直接算5分钟做rate这是什么意思?看左侧生成一个即时向量,它计算出5XX响应码各类请求的增长速率,这叫增长率右边也会生成一个及时向量,它计算出所有标签组合是代表的各类请求的增长速率。意思是不光有5XX,2XX,3XX是不是也都有?各位明白各自都有。但是我们现在的意思是我们看哪一类?

看计算时promql会在操作符左右两侧各找一个标签完全匹配的元素进行比较,其意义为计算出每类请求当中5XX响应码请求所样本比例每类请求中的5XX响应码在该类型中所占的比例。如果左右标签完全匹配意味着什么?左右标签完全匹配的时候意味着什么?大家思考一下,我们是不是可以认为左侧的rate它其实得到的即时向量的元素要少于右侧,是不是因为这里有过滤条件?刚才说这里满足5XX的响应码可能有这样三个时间序列这里的意思就是对这3个时间序列各自用这个函数进行计算是不是会生成3个对应的时新时间序列,它的标签值是一样第一,本身HTP request total对它过滤就会生成一个时间序列,对各自时间序列按5分钟求平均值,5分钟平均一次,每一个样本轴往前推,是不是生成一个新的时间序列?这个时间序列叫增长率,等时间序列。对于这个时间序列,我们要取什么?及时向量,取出来最新值。这是三个假设这3个。而第二个意思表示什么?这里有加标签限制吗?没有,就意味着指标下的所有的时间序列是不是都可能包含进来?所有的都包含进来,跟刚才一样,我们要对它做什么?做运算,而且又以5分钟为范围,这是两个范围,需要一样,不然它没有什么比较意义。会生成一个新的增长率时间序列。因为说过这里是采样值,它们都是计数器。

对计数器,我们取值以后会生成一个新的叫做增长率的时间序列。增长序列是不是每一个设备也有个值?这就是及时向量。现在我就查找一个及时向量与及时向量它的值,它的标签完全一样。标签完全一样的意味着什么?对于标签完全一样指的是对右侧而言,你想象一下,左右只说标签完全一样,没说标签值。所以这就意味着对于右侧而言,很有可能对同一个URL响应码下,比如我们以API为例,它可能是不是会有5XX响应码,2XX响应码,3XX响应码,不是要右侧都匹配?大概是这么结果。这里大家可能理解起稍微有点难度,这里边可能会有问题,表达式里边会有问题,在比较上和他所期望表达的意义上会有偏差。所以我们先看后面示例,再回头来纠正他,这个应该容易理解,因为1对于1没什么特别难的地方。

首先看正常情况下,这是一个示例输出。我是在官方网站上截出。查询操作是这样的method_code:http_requests:rate5m,可以理解为这是一个叫做记录规则或者是一个内置的比较独特的指标。等下我们会讲到记录规则,我们先想象成这个指标名,它的指标名比较诡异。有这么两个标签method应该他们做分别的统计。差不多意思就是http,error就是http请求当中发生错误的每5分钟的速率,最近一次的样本值是24,因为这得到的是即时样本,code等于五百,很显然这就是错误。而错误也要分类,有500响应码,还有404响应码,还有501响应码等,有各种各样的响应码。所以它统计出结果是或者叫我们取值的结果是差不多得到的结果一个是24,一个是30,这个是36,这个是21。但是它的方法注意这里的标签code。标签虽然各有不同,method也各有不同。这只是组合出来的结果。这叫组合出来的结果。意思就是get方法500有二十四个,这个就能理解。get方法404,不是30,不是有二十四个。应该认为它叫增长率,最近一次的增长平均最近5分钟的平均增长率大概是这么多个,这是30个。put501的是3个post,500的是6个,post40次的是21个。这是分别做的一个速率计算,而且那是各自速率计算的最近一次的样本。所以这是个即时样本取得或者叫及时向量。

第二个计算,它不是基于响应码算的,而是基于方法做统计计算的。注意这是另外一个指标,在这个指标下,它的意思是统计各个方法在过去5分钟中,大体上我们的请求的数量增长多少个?能看到这意思仍然增长率。所以过去5分钟的平均增长率大概get方法,不管它是什么,响应码是600个,tell方法是34个,post方法是120个。接下我们要在它俩之间进行比较,比较时我们要做什么?这是做什么运算?除法运算,我希望得出来一个比例值,这是做除法运算,所以这是直接计算比例值。得到的结果就是一个所谓的占比例。描述的应该是类似于后面这种结构的计算结果,计算方法,而不是使用大于小于比较。我们继续看,正常情况下我们得到的数量应该怎么计算?首先,这里有一个重要的字段,叫做ignoring code。做左右两侧标签比较时,要忽略code,忽略code意味什么?意味着我们不看code码的值比较方法,所以得到结果看它怎么比较。首先,对于左侧来讲,我们取出code等于500的序列值为10分二十四。首先至少说get方法是24,post方法是500,这能理解。因此对左侧而言,它有两个值,一个是24,一个是6,这是集合。对右侧method rate。我们求的结果是什么?同样的逻辑,我们这里没指任何条件,因此是634和120集合,双方进行比较的时候,标签这是不是有两个,一个叫method,一个叫code。后面标签有几个?六百的标签有几个?只有一个 method 等于 get, 24标签有几个?method 等于 get,一个code等于500。但是底下除这里要干什么,忽略code是没问题。忽略code第一个method等于get,24底下method等于什么?是pose的吗?从右侧找method 等于 get应该标签名和标签值完全一致的,不光是标签名,要标签名和标签完全都一致,它表示24和600连接,还有其他可能性没有。底下method跟他的method都完全不一样,所以结果是什么?24/600,下面对6而言,它的method等于什么?post,code等于500。但是比较的时候我们要ignore code。因为从右侧找一个method是Post值的是多少?一百二。因此它要用六和一百二进行连接。右侧三十四没出现,没有匹配的值就不出现。所以计算结果method等于get是0.04,method等于post是0.05。这样容易看得懂。但是前面稍微麻烦,因为我们说的太含糊。所以太含糊指的是它一共有多少个标签我们也没说,我们只能假设他只有这一个标签。我们只能假设他只有这一个标签,叫status等于code。假设这个指标只有一个标签,叫status等于code。只能这样算。如果有多个标签,我们后面的逻辑上就很难理解出来到底什么意思。我们假设是这样期望。我把示例给大家改,看能不能改成我们更容易理解的地方。比如假设我们的http_requests_ total,它有这样两个标签,一个叫status_code,叫pass,我们形态叫路径。我们借助这么一个时间序列去统计每一类响应码在它所属的这样一个pass上对应的占的比例是多少,或者占的比例是不是大于10%。我们去求每一类所谓指的是每一类pass请求当中就同一个pass下,开始各类请求一定有一个增长率,有一个增长率,后500的响应码的叫五叉叉响应码也有一个增长率。现在去求5XX响应码的增长率在同一个pass下的增长率的比例中占比是不是超过10%。计算5XX响应码,在这么一个指标以pass为例来统计它的增长率占比是不是超过10%?怎么计算?我们还要对每一个pass求和的是不是这意思。我们进行计算,首先取出5XX响应码各自的增长率是多少?很显然,刚才各位应该知道rate,以5分钟为例,rate(http_requests_total(status_code=~”5.*”),我们要做模式匹配,我就写一个符号叫五点星,这种格式对它进行加上范围向量,5分钟求平均值,这就会得出来一个速率。但是这个速率它计算的结果就是每一个路径下的5XX响应码,速率没问题。

image.png

相关文章
|
2月前
|
存储 Prometheus Cloud Native
「译文」Prometheus 查询语言 PromQL 简介
「译文」Prometheus 查询语言 PromQL 简介
|
Prometheus Cloud Native 开发者
|
存储 Prometheus 监控
|
存储 Prometheus 监控
PromQL 进阶|学习笔记(一)
快速学习 PromQL 进阶
175 0
|
自然语言处理 索引
EleasticSearch(四)进阶查询
EleasticSearch(四)进阶查询
143 0
|
存储 数据采集 Prometheus
PromQL 使用基础|学习笔记(四)
快速学习 PromQL 使用基础
209 0
PromQL 使用基础|学习笔记(四)
|
存储 Prometheus 监控
PromQL 使用基础|学习笔记(三)
快速学习 PromQL 使用基础
532 0
PromQL 使用基础|学习笔记(三)
|
Prometheus Cloud Native 开发者
PromQL 使用基础|学习笔记(二)
快速学习 PromQL 使用基础
314 0
PromQL 使用基础|学习笔记(二)
|
存储 Prometheus 监控
PromQL 使用基础|学习笔记(一)
快速学习 PromQL 使用基础
325 0
PromQL 使用基础|学习笔记(一)
|
Prometheus Cloud Native 开发者
Prometheus 进阶|学习笔记(四)
快速学习 Prometheus 进阶
460 0
Prometheus 进阶|学习笔记(四)