运维别卷系列 - 云原生监控平台 之 04.prometheus 查询语句 promql 实践
Prometheus 提供了一种称为 PromQL(Prometheus 查询语言)的功能查询语言,允许用户实时选择和聚合时间序列数据。表达式的结果可以显示为图形,在 Prometheus 的表达式浏览器中查看为表格数据,也可以通过 HTTP API 由外部系统使用。同一指标和同一组标记维度的时间戳值流。Prometheus 将所有数据存储为时间序列。时间序列 = 指标名称{label_name=
PromQL 简介
- Prometheus provides a functional query language called PromQL (Prometheus Query Language) that lets the user select and aggregate time series data in real time. The result of an expression can either be shown as a graph, viewed as tabular data in Prometheus’s expression browser, or consumed by external systems via the HTTP API.
- Prometheus 提供了一种称为 PromQL(Prometheus 查询语言)的功能查询语言,允许用户实时选择和聚合时间序列数据。表达式的结果可以显示为图形,在 Prometheus 的表达式浏览器中查看为表格数据,也可以通过 HTTP API 由外部系统使用。
什么是时间序列
- 同一指标和同一组标记维度的时间戳值流。Prometheus 将所有数据存储为时间序列。
时间序列 = 指标名称{label_name="label_value"}
- PromQL 执行出来的每一行,都属于时间序列,即使指标名称是相同的,但是 label 肯定是不同的
PromQL 数据类型
在 Prometheus 的表达式语言中,表达式或子表达式的计算结果可以达到以下四种类型之一
即时向量 Instant vector
即时向量
:一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳
- 三种查询组合:
只使用标签名称,如:
node_memory_MemAvailable_bytes
只使用 label,如:
{instance="192.168.11.167:9100"}
标签名称加 label,如:
node_memory_MemAvailable_bytes{instance="192.168.11.167:9100"}
如果有多个 label 可以写成
node_memory_MemAvailable_bytes{instance="192.168.11.167:9100",app="node-exporter"}
,用逗号分隔多个 label
Instant vector
支持匹配运算,也只是使用正则表达式来匹配- 正则表达式匹配是完全锚定的。
- 匹配项
env=~"foo"
被视为env=~"^foo$"
。
- 匹配项
=
:选择与提供的字符串完全相等的标签。
这个上面已经展示过了,这里就不展示了
!=
:选择不等于提供的字符串的标签。
node_disk_read_time_seconds_total{device!="dm-0"}
=~
:选择与所提供字符串正则表达式匹配的标签。
node_disk_read_time_seconds_total{device=~"sd.*"}
!~
:选择与提供的字符串正则表达式不匹配的标签。
node_disk_read_time_seconds_total{device!~"sr.*|dm.*"}
- 指标名称不得是关键字
bool
、on
、ignoring
、group_left
和group_right
之一。以下表达是非法的:on{}
- 此限制的解决方法是使用
__name__
标签:{__name__="on"}
- 此限制的解决方法是使用
范围向量 Range vector
范围向量
:一组时间序列,包含每个时间序列随时间变化的数据点范围
- 在 即时向量(Instant vector) 的基础上,后面加上
[持续时间]
以指定应为每个生成的范围向量元素获取多长时间的时间值。范围是一个闭合区间,即时间戳与范围任一边界重合的样本仍包含在选择中。
Time Durations
- 持续时间(Time Durations)指定为一个数字。必须使用整数时间。
- 持续时间可以通过串联进行组合。单位必须按从长到短的顺序排列。给定单位在一段时间内只能出现一次。例如 1h30m,不能使用 1.5h。
- 即时向量(Instant vector)后面跟以下单位之一:
ms
:毫秒s
:秒m
:分钟h
:小时d
:天(假设一天总是有 24 小时)w
:星期(假设一周总是有 7 天)y
:年(假设一年总是有 365 天)- 对于一年中的几天,闰日被忽略,相反,一分钟,闰秒被忽略
过去五分钟内的一组样本,@后面的是时间戳,是毫秒级别的
node_disk_read_time_seconds_total{device!~"sr.*|dm.*"} [5m]
Offset modifier
offset
修饰符允许更改查询中单个即时和范围向量的时间偏移量。
当前时间起,五分钟前的时间序列
node_disk_read_time_seconds_total{device!~"sr.*|dm.*"} offset 5m
@ modifier
@
修饰符允许更改查询中单个即时和范围向量的计算时间。提供给@
修饰符的时间是一个 unix 时间戳,并用浮点数文字描述。
查看 2024-05-04 21:35:16 这个时候的值,时间戳的单位是秒
node_disk_read_time_seconds_total{device!~"sr.*|dm.*"} @ 1714829716
浮点值 Scalar
标量
:一个简单的数值浮点值
字符串 String
字符串
:一个简单的字符串值;当前未使用
PromQL FUNCTIONS
Prometheus 有很多内置的函数,感兴趣的,可以看看官方文档,这里就挑几个用的比较多的函数
floor()
样本值向下舍入到最接近的整数。
上面
@ modifier
这块的 PromQL 取的值是一堆小数点,加上floor()
函数之后,就变成整数了(从1.5050000000000001
变成了1
)
floor(node_disk_read_time_seconds_total{device!~"sr.*|dm.*"} @ 1714829716)
irate()
计算范围向量中时间序列的每秒瞬时增长率。这是基于最后两个数据点。单调性的中断(例如由于目标重新启动而导致的计数器复位)会自动调整。
以下示例表达式返回范围向量中每个时间序列最多 20 分钟的 HTTP 请求的每秒速率:
irate(prometheus_http_requests_total[20m])
rate()
计算范围向量中时间序列的每秒平均增长率。单调性的中断(例如由于目标重新启动而导致的计数器复位)会自动调整。此外,计算外推到时间范围的末端,允许漏掉刮擦或刮擦周期与范围的时间段不完美对齐。
以下示例表达式返回过去 20 分钟内每个时间序列在范围向量中测量的每秒 HTTP 请求速率:
rate(prometheus_http_requests_total [20m])
round()
样本值四舍五入到最接近的整数。通过四舍五入来解决关系。可选的 to_nearest 参数允许指定样本值应舍入到的最接近倍数。这个倍数也可能是一个分数。
上面
@ modifier
这块的 PromQL 取的值是一堆小数点,加上round()
函数之后,就变成整数了(从1.5050000000000001
变成了2
)
round(node_disk_read_time_seconds_total{device!~"sr.*|dm.*"} @ 1714829716)
sort()
返回按样本值升序排序的向量元素。只能用在即时向量,用在范围向量会报错:
parse error: expected type instant vector in call to function "sort_desc", got range vector
sort_desc()
与
sort
相同,但按降序排序。
PromQL 运算符
算术运算符
运算符 | 运算作用 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取模 |
^ | 幂 |
计算内存使用率
((node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / node_memory_MemTotal_bytes ) * 100
比较运算符
运算符 | 运算作用 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
内存使用率大于 10% 的
((node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / node_memory_MemTotal_bytes ) * 100 > 10
聚合运算符
运算符 | 运算作用 |
---|---|
sum() | 对样本值求和 |
min() | 求取样本值中的最小者 |
max() | 求取样本值中的最大者 |
avg() | 对样本值求平均值 |
group() | 结果向量中的所有值均为 1 |
stddev() | 对样本值求标准差,以帮助用户了解数据的波动大小(或称之为波动程度) |
stdvar() | 对样本值求方差,它是求取标准差过程中的中间状态 |
count() | 对分组内的时间序列进行数量统计 |
count_values() | 对分组内的时间序列的样本值进行数量统计,即等于某值的样本个数 |
bottomk() | 按样本值计算的最小 k 个元素 |
topk() | 按样本值计算的最大 k 个元素 |
quantile() | 计算维度的 φ 分位数 (0 ≤ φ ≤ 1) |
- 这些运算符可用于聚合所有标签维度,也可以通过包含
without
或by
子句来保留不同的维度。这些子句可以在表达式之前或之后使用。
without
从结果向量中删除列出的标签,而所有其他标签保留在输出中。by
反其道而行之,删除by
子句中未列出的标签,即使它们的标签值在向量的所有元素之间都相同。
更多推荐
所有评论(0)