Kubernetes Prometheus 系列 | PromQL的使用

5 篇文章 0 订阅
3 篇文章 0 订阅

第3章PromQL 介绍

Prometheus 通过指标名称(metrics name)以及对应的一组标签(labelset)唯一定义一条时间序列。指标名称反映了监控样本的基本标识,而 label 则在这个基本特征上为采集到的数据提供了多种特征维度。用户可以基于这些特征维度过滤,聚合,统计从而产生新的计算后的一条时间序列。PromQL 是 Prometheus 内置的数据查询语言,其提供对时间序列数据丰富的查询,聚合以及逻辑运算能力的支持。并且被广泛应用在 Prometheus的日常应用当中,包括对数据查询、可视化、告警处理当中。可以这么说,PromQL 是Prometheus 所有应用场景的基础,理解和掌握 PromQL 是 Prometheus 入门的第一课。

3.1 基本用法

3.1.1 查询时间序列

当 Prometheus 通过 Exporter 采集到相应的监控指标样本数据后,我们就可以通过
PromQL 对监控样本数据进行查询。
当我们直接使用监控指标名称查询时,可以查询该指标下的所有时间序列。如:
prometheus_http_requests_total
等同于:
prometheus_http_requests_total{}
该表达式会返回指标名称为 prometheus_http_requests_total 的所有时间序列:
prometheus_http_requests_total{code=“200”,handler=“alerts”,instance=“localhost:9090”,j
ob=“prometheus”,method=“get”}= (20889@1518096812.326)
prometheus_http_requests_total{code=“200”,handler=“graph”,instance=“localhost:9090”,jo
b=“prometheus”,method=“get”}= (21287@1518096812.326)
PromQL 还支持用户根据时间序列的标签匹配模式来对时间序列进行过滤,目前主要
支持两种匹配模式:完全匹配和正则匹配。
➢ PromQL 支持使用 = 和 != 两种完全匹配模式:
⚫ 通过使用 label=value 可以选择那些标签满足表达式定义的时间序列;
⚫ 反之使用 label!=value 则可以根据标签匹配排除时间序列;
例如,如果我们只需要查询所有 prometheus_http_requests_total 时间序列中满足标
签 instance 为 localhost:9090 的时间 序列,则可以使用如下表达式:
prometheus_http_requests_total{instance=“localhost:9090”}
反之使用 instance!=“localhost:9090” 则可以排除这些时间序列:
prometheus_http_requests_total{instance!=“localhost:9090”}
➢ PromQL还可以支持使用正则表达式作为匹配条件,多个表达式之间使用 | 进行分离:
⚫ 使用 label=~regx 表示选择那些标签符合正则表达式定义的时间序列;
⚫ 反之使用 label!~regx 进行排除;
例如,如果想查询多个环节下的时间序列序列可以使用如下表达式:
prometheus_http_requests_total{environment=~“staging|testing|development”,method!="GET
"}
排除用法
prometheus_http_requests_total{environment!~“staging|testing|development”,method!="GET
"}

3.1.2 范围查询

直接通过类似于 PromQL 表达式 httprequeststotal 查询时间序列时,返回值中只会
包含该时间序列中的最新的一个样本值,这样的返回结果我们称之为瞬时向量。而相应的这
样的表达式称之为__瞬时向量表达式。
而如果我们想过去一段时间范围内的样本数据时,我们则需要使用区间向量表达式。区
间向量表达式和瞬时向量表达式之间的差异在于在区间向量表达式中我们需要定义时间选
择的范围,时间范围通过时间范围选择器 [] 进行定义。 例如,通过以下表达式可以选择
最近 5 分钟内的所有样本数据:
prometheus_http_requests_total{}[5m]
该表达式将会返回查询到的时间序列中最近 5 分钟的所有样本数据:
prometheus_http_requests_total{code=“200”,handler=“alerts”,instance=“localhost:9090”,j
ob=“prometheus”,method=“get”}=[
1@1518096812.326
1@1518096817.326
1@1518096822.326
1@1518096827.326
1@1518096832.326
1@1518096837.325
] 9.
prometheus_http_requests_total{code=“200”,handler=“graph”,instance=“localhost:9090”,jo
b=“prometheus”,method=“get”}=[
4@1518096812.326
4@1518096817.326
4@1518096822.326
4@1518096827.326
4@1518096832.326
4@1518096837.325
]
通过区间向量表达式查询到的结果我们称为区间向量。 除了使用 m 表示分钟以外,
PromQL 的时间范围选择器支持其它时间单位:
⚫ s - 秒
⚫ m - 分钟
⚫ h - 小时
⚫ d - 天
⚫ w - 周
⚫ y - 年

3.1.3 时间位移操作

在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准:
prometheus_http_requests_total{} # 瞬时向量表达式,选择当前最新的数据
prometheus_http_requests_total{}[5m] # 区间向量表达式,选择以当前时间为基准,
5 分钟内的数据

而如果我们想查询,5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据呢? 这
个时候我们就可以使用位移操作,位移操作的关键字为 offset。 可以使用 offset 时间位移
操作:
prometheus_http_requests_total{} offset 5m
prometheus_http_requests_total{}[1d] offset 1d

3.1.4 使用聚合操作

一般来说,如果描述样本特征的标签(label)在并非唯一的情况下,通过 PromQL 查询
数据,会返回多条满足这些特征维度的时间序列。而 PromQL 提供的聚合操作可以用来对
这些时间序列进行处理,形成一条新的时间序列:

# 查询系统所有 http 请求的总量
sum(prometheus_http_requests_total)
# 按照 mode 计算主机 CPU 的平均使用时间
avg(node_cpu_seconds_total) by (mode)
# 按照主机查询各个主机的 CPU 使用率
sum(sum(irate(node_cpu_seconds_total{mode!='idle'}[5m])) / sum(irate(node_cpu_
seconds_total [5m]))) by (instance) 
3.1.5 标量和字符串

除了使用瞬时向量表达式和区间向量表达式以外,PromQL 还直接支持用户使用标量
(Scalar)和字符串(String)。
➢ 标量(Scalar):一个浮点型的数字值
标量只有一个数字,没有时序。 例如:
10
需要注意的是,当使用表达式 count(prometheus_http_requests_total),返回的数
据类型,依然是瞬时向量。用户可以通过内置函数 scalar()将单个瞬时向量转换为标量。
➢ 字符串(String):一个简单的字符串值
直接使用字符串,作为 PromQL 表达式,则会直接返回字符串。

“this is a string”
‘these are unescaped: \n \ \t’
these are not unescaped: \n ' " \t

3.1.6 合法的 PromQL 表达式

所有的 PromQL 表达式都必须至少包含一个指标名称(例如 http_request_total),或者
一个不会匹配到空字符串的标签过滤器(例如{code=”200”})。
因此以下两种方式,均为合法的表达式:
prometheus_http_requests_total # 合法
prometheus_http_requests_total{} # 合法
{method=“get”} # 合法
而如下表达式,则不合法:
{job=~“.*”} # 不合法
同时,除了使用 {label=value} 的形式以外,我们还可以使用内置的 name 标签
来指定监控指标名称:
{name=~“prometheus_http_requests_total”} # 合法
{name=~“node_disk_bytes_read|node_disk_bytes_written”} # 合法

3.2 PromQL 操作符

使用 PromQL 除了能够方便的按照查询和过滤时间序列以外,PromQL 还支持丰富的
操作符,用户可以使用这些操作符对进一步的对事件序列进行二次加工。这些操作符包括:
数学运算符,逻辑运算符,布尔运算符等等。

3.2.1 数学运算

PromQL 支持的所有数学运算符如下所示:
⚫ + (加法)
⚫ - (减法)
⚫ * (乘法)
⚫ / (除法)
⚫ % (求余)
⚫ ^ (幂运算)

3.2.2 布尔运算

➢ Prometheus 支持以下布尔运算符如下:
⚫ == (相等)
⚫ != (不相等)
⚫ >(大于)
⚫ < (小于)
⚫ >= (大于等于)
⚫ <= (小于等于)
➢ 使用 bool 修饰符改变布尔运算符的行为
布尔运算符的默认行为是对时序数据进行过滤。而在其它的情况下我们可能需要的是真
正的布尔结果。例如,只需要 知道当前模块的 HTTP 请求量是否>=1000,如果大于等于
1000 则返回 1(true)否则返回 0(false)。这时可以使 用 bool 修饰符改变布尔运算的
默认行为。 例如:
prometheus_http_requests_total > bool 1000
使用 bool 修改符后,布尔运算不会对时间序列进行过滤,而是直接依次瞬时向量中的
各个样本数据与标量的比较结果 0 或者 1。从而形成一条新的时间序列。
prometheus_http_requests_total{code=“200”,handler=“query”,instance=“localhost:9090”,jo
b=“prometheus”,method=“get”} 1
prometheus_http_requests_total{code=“200”,handler=“query_range”,instance=“localhost:90
90”,job=“prometheus”,method=“get”} 0
同时需要注意的是,如果是在两个标量之间使用布尔运算,则必须使用 bool 修饰符
2 == bool 2 # 结果为 1

3.2.3 使用集合运算符

使用瞬时向量表达式能够获取到一个包含多个时间序列的集合,我们称为瞬时向量。通
过集合运算,可以在两个瞬时向量与瞬时向量之间进行相应的集合操作。
目前,Prometheus 支持以下集合运算符:
⚫ and (并且)
⚫ or (或者)
⚫ unless (排除)
vector1 and vector2 会产生一个由 vector1 的元素组成的新的向量。该向量包含
vector1 中完全匹配 vector2 中的元素组成。
vector1 or vector2 会产生一个新的向量,该向量包含 vector1 中所有的样本数据,
以及 vector2 中没有与 vector1 匹配到的样本数据。
vector1 unless vector2 会产生一个新的向量,新向量中的元素由 vector1 中没有与
vector2 匹配的元素组成。

3.2.4 操作符优先级

对于复杂类型的表达式,需要了解运算操作的运行优先级。例如,查询主机的 CPU 使
用率,可以使用表达式:
100 * (1 - avg (irate(node_cpu_seconds_total{mode=‘idle’}[5m])) by(job) )
其中irate是PromQL中的内置函数,用于计算区间向量中时间序列每秒的即时增长率。
在 PromQL 操作符中优先级由高到低依次为:
⚫ ^
⚫ *, /, %
⚫ +, -
⚫ ==, !=, <=, =, >
⚫ and, unless
⚫ or

3.2.5 PromQL 聚合操作

Prometheus 还提供了下列内置的聚合操作符,这些操作符作用域瞬时向量。可以将瞬
时表达式返回的样本数据进行 聚合,形成一个新的时间序列。
⚫ sum (求和)
⚫ min (最小值)
⚫ max (最大值)
⚫ avg (平均值)
⚫ stddev (标准差)
⚫ stdvar (标准差异)
⚫ count (计数)
⚫ count_values (对 value 进行计数)
⚫ bottomk (后 n 条时序)
⚫ topk (前 n 条时序)
⚫ quantile (分布统计)
使用聚合操作的语法如下:
([parameter,] ) [without|by (

without 用于从计算结果中移除列举的标签,而保留其它标签。by 则正好相反,结果
向量中只保留列出的标签,其余标签则移除。通过 without 和 by 可以按照样本的问题对数
据进行聚合。
例如:
sum(prometheus_http_requests_total) without (instance)
等价于
sum(prometheus_http_requests_total) by (code,handler,job,method)
如果只需要计算整个应用的 HTTP 请求总量,可以直接使用表达式:
sum(prometheus_http_requests_total)
count_values 用于时间序列中每一个样本值出现的次数。count_values 会为每一个唯一的
样本值输出一个时间序列,并且每一个时间序列包含一个额外的标签。 例如:
count_values(“count”, prometheus_http_requests_total)
topk 和 bottomk 则用于对样本值进行排序,返回当前样本值前 n 位,或者后 n 位的
时间序列。
获取 HTTP 请求数前 5 位的时序样本数据,可以使用表达式:
topk(5, prometheus_http_requests_total)
quantile 用于计算当前样本数据值的分布情况 quantile(φ, express)其中 0 ≤ φ ≤ 1。
例如,当 φ 为 0.5 时,即表示找到当前样本数据中的中位数:
quantile(0.5, prometheus_http_requests_total)

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值