Prometheus监控学习笔记之初识PromQL
0x00 概述
Prometheus 提供了⼀种功能表达式语⾔PromQL,允许⽤户实时选择和汇聚时间序列数据。表达式的结果可以在浏览器中显⽰为图形,也可以显⽰为表格数据,或者由外部系统通过调⽤。
0x01 表达式语⾔数据类型
在 Prometheus 的表达式语⾔中,表达式或⼦表达式包括以下四种类型之⼀:
瞬时向量(Instant vector) - ⼀组时间序列,每个时间序列包含单个样本,它们共享相同的时间戳。也就是说,表达式的返回值中只会包含该时间序列中的最新的⼀个样本值。⽽相应的这样的表达式称之为瞬时向量表达式。
区间向量(Range vector) - ⼀组时间序列,每个时间序列包含⼀段时间范围内的样本数据。
标量(Scalar) - ⼀个浮点型的数据值。
字符串(String) - ⼀个简单的字符串值。
根⽤户输⼊的表达式返回的数据类型是否合法取决于⽤例的不同,例如:瞬时向量表达式返回的数据类型是唯⼀可以直接
绘制成图表的数据类型。
0x02 字⾯量
字符串
字符串可以⽤单引号、双引号或反引号指定为⽂字常量。
PromQL 遵循。在单引号或双引号中,⽤反斜杠来表⽰转义序列,后⾯可以跟a, b, f, n, r, t, v或\。特殊字符可以使⽤⼋进制(\nnn)或者⼗六进制(\xnn,\unnnn和\Unnnnnnnn)。
与 Go 不同,Prometheus 不会对反引号内的换⾏符进⾏转义。
例如:
"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`
标量
标量浮点值可以字⾯上写成[-](digits)[.(digits)]的形式。
-2.43
0x03 时间序列过滤器
瞬时向量过滤器
瞬时向量过滤器允许在指定的时间戳内选择⼀组时间序列和每个时间序列的单个样本值。在最简单的形式中,近指定指标(metric)名称。这将⽣成包含此指标名称的所有时间序列的元素的瞬时向量。
例如:选择指标名称为http_requests_total的所有时间序列:
http_requests_total
可以通过向花括号({})⾥附加⼀组标签来进⼀步过滤时间序列。
例如:选择指标名称为http_requests_total,job标签值为prometheus,group标签值为canary的时间序列:
http_requests_total{job="prometheus",group="canary"}
PromQL 还⽀持⽤户根据时间序列的标签匹配模式来对时间序列进⾏过滤,⽬前主要⽀持两种匹配模式:完全匹配和正则匹配。总共有以下⼏种标签匹配运算符:
= : 选择与提供的字符串完全相同的标签。
!= : 选择与提供的字符串不相同的标签。
=~ : 选择正则表达式与提供的字符串(或⼦字符串)相匹配的标签。
!~ : 选择正则表达式与提供的字符串(或⼦字符串)不匹配的标签。
例如:选择指标名称为http_requests_total,环境为staging、testing或development,HTTP ⽅法为GET的时间序列:
http_requests_total{environment=~"staging|testing|development",method!="GET"}
没有指定标签的标签过滤器会选择该指标名称的所有时间序列。
所有的 PromQL 表达式必须⾄少包含⼀个指标名称,或者⼀个不会匹配到空字符串的标签过滤器。
以下表达式是⾮法的(因为会匹配到空字符串):
{job=~".*"} # ⾮法!
以下表达式是合法的:
{job=~".+"} # 合法!
{job=~".*",method="get"} # 合法!
除了使⽤<metric name>{label=value}的形式以外,我们还可以使⽤内置的__name__标签来指定监控指标名称。例如:表达式http_requests_total 等效于{__name__="http_requests_total"}。也可以使⽤除=之外的过滤器(=,=~,~)。以下表达式选择指标名称以job:开头的所有指标:
{__name__=~"job:.*"}
Prometheus 中的所有正则表达式都使⽤。
0x04 区间向量过滤器
区间向量与瞬时向量的⼯作⽅式类似,唯⼀的差异在于在区间向量表达式中我们需要定义时间选择的范围,时间范围通过时间范围选择器[]进⾏定义,以指定应为每个返回的区间向量样本值中提取多长的时间范围。
时间范围通过数字来表⽰,单位可以使⽤以下其中之⼀的时间单位:
正则匹配两个字符之间的字符串s - 秒
m - 分钟
h - ⼩时
d - 天
w - 周
y - 年
例如:选择在过去 5 分钟内指标名称为http_requests_total,job标签值为prometheus的所有时间序列:
http_requests_total{job="prometheus"}[5m]
0x05 时间位移操作
在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准:
http_request_total{} # 瞬时向量表达式,选择当前最新的数据
http_request_total{}[5m] # 区间向量表达式,选择以当前时间为基准,5分钟内的数据
⽽如果我们想查询,5 分钟前的瞬时样本数据,或昨天⼀天的区间内的样本数据呢? 这个时候我们就可以使⽤位移操作,位移操作的关键字为offset。
例如,以下表达式返回相对于当前查询时间过去 5 分钟的http_requests_total值:
http_requests_total offset 5m
注意:offset 关键字需要紧跟在选择器({})后⾯。以下表达式是正确的:
sum(http_requests_total{method="GET"} offset 5m) #合法
下⾯的表达式是不合法的:
sum(http_requests_total{method="GET"}) offset 5m # 错误
该操作同样适⽤于区间向量。以下表达式返回指标http_requests_total⼀周前的 5 分钟之内的 HTTP 请求量的增长率:
rate(http_requests_total[5m] offset 1w)
0x06 操作符
使⽤PromQL除了能够⽅便的按照查询和过滤时间序列以外,PromQL还⽀持丰富的操作符,⽤户可以使⽤这些操作符对进⼀步的对事件序列进⾏⼆次加⼯。这些操作符包括:数学运算符,逻辑运算符,布尔运算符等等。详细描述请参考。
0x07 内置函数
Prometheus 提供了⼤量的内置函数来处理时序数据,详细描述请参考。
0x08 陷阱
失效
执⾏查询操作时,独⽴于当前时刻被选中的时间序列数据所对应的时间戳,这个时间戳主要⽤来进⾏聚合操作,包括sum, avg等,⼤多数聚合的时间序列数据所对应的时间戳没有对齐。由于它们的独⽴性,我们需要在这些时间戳中选择⼀个时间戳,并已这个时间戳为基准,获取⼩于且最接近这个时间戳的时间序列数据。
如果采样⽬标或告警规则不再返回之前存在的时间序列的样本,则该时间序列将被标记为失效。如果删除了采样⽬标,则之前返回的时间序列也会很快被标记为失效。
如果在某个时间序列被标记为失效后在该时间戳处执⾏查询操作,则不会为该时间序列返回任何值。如果随后在该时间序列中插⼊了新的样本,则照常返回时间序列数据。
如果在采样时间戳前 5 分钟(默认情况)未到任何样本,则该时间戳不会返回任何任何该时间序列的值。这实际上意味着你在图表中看到的数据都是在当前时刻 5 分钟前的数据。
对于在采样点中包含时间戳的时间序列,不会被标记为失效。在这种情况下,仅使⽤ 5 分钟阈值检测的规则。
避免慢查询和⾼负载
如果⼀个查询需要操作⾮常⼤的数据量,图表绘制很可能会超时,或者服务器负载过⾼。因此,在对未知数据构建查询时,始终需要在Prometheus 表达式浏览器的表格视图中构建查询,直到结果是看起来合理的(最多为数百个,⽽不是数千个)。只有当你已经充分过滤或者聚合数据时,才切换到图表模式。如果表达式的查询结果仍然需要很长时间才能绘制出来,则需要通过记录规则重新清洗数据。
像api_http_requests_total这样简单的度量指标名称选择器,可以扩展到具有不同标签的数千个时间序列中,这对于 Prometheus 的查询语⾔是⾮常重要的。还要记住,对于聚合操作来说,即使输出的时间序列集⾮常少,它也会在服务器上产⽣负载。这类似于在关系型数据库中查询⼀个字段的总和,总是⾮常缓慢。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论