数据查询

数据查询

查询时间序列

当 Prometheus 通过 Exporter 采集到相应的监控指标样本数据后,我们就可以通过 PromQL 对监控样本数据进行查询。当我们直接使用监控指标名称查询时,可以查询该指标下的所有时间序列。如:

http_requests_total

http_requests_total{}

http_requests_total{code="200",handler="alerts",instance="localhost:9090",job="prometheus",method="get"}=(20889@1518096812.326)
http_requests_total{code="200",handler="graph",instance="localhost:9090",job="prometheus",method="get"}=(21287@1518096812.326)

匹配模式

PromQL 还支持用户根据时间序列的标签匹配模式来对时间序列进行过滤,目前主要支持两种匹配模式:完全匹配和正则匹配。PromQL 支持使用 = 和 != 两种完全匹配模式:

  • 通过使用 label=value 可以选择那些标签满足表达式定义的时间序列;
  • 反之使用 label!=value 则可以根据标签匹配排除时间序列;

例如,如果我们只需要查询所有 http_requests_total 时间序列中满足标签 instance 为 localhost:9090 的时间序列,则可以使用如下表达式:

http_requests_total{instance="localhost:9090"}
# 排除掉这些时间序列
http_requests_total{instance!="localhost:9090"}

除了使用完全匹配的方式对时间序列进行过滤以外,PromQL 还可以支持使用正则表达式作为匹配条件,多个表达式之间使用 | 进行分离:使用 label=~regx 表示选择那些标签符合正则表达式定义的时间序列;反之使用 label!~regx 进行排除。例如,如果想查询多个环节下的时间序列序列可以使用如下表达式:

http_requests_total{environment=~"staging|testing|development",method!="GET"}

范围查询

直接通过类似于 PromQL 表达式 http_requests_total 查询时间序列时,返回值中只会包含该时间序列中的最新的一个样本值,这样的返回结果我们称之为瞬时向量;而相应的这样的表达式称之为瞬时向量表达式。范围向量选择器像瞬时向量选择器一样工作,不同的是它们从时间序列中选择一定时间范围内的数据。在语法上,范围持续时间附加在向量选择器末尾的方括号([])中。

时间持续的值以数字表示,其后跟以下时间单位:

  • s - 秒
  • m - 分钟
  • h - 小时
  • d - 天
  • w - 周
  • y - 年

在此示例中,我们选择在过去 1 分钟内为 metric 为 prometheus_http_requests_total 且 job 标签设置为 prometheus 的所有时间序列记录的元素值:

prometheus_http_requests_total{job="prometheus"}[1m]

范围查询示意图

偏移修改器

偏移修改器允许更改查询中各个瞬时和范围向量的时间偏移。例如,以下表达式返回相对于当前查询时间 5 分钟前 metric 为 http_requests_total 的元素值:

http_requests_total offset 5m

# 偏移修改器始终需要跟随在选择器之后
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
sum(http_requests_total{method="GET"}) offset 5m // INVALID.

# 也适用于范围向量
rate(http_requests_total[5m] offset 1w)

聚合操作

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

# 查询系统所有http请求的总量
sum(http_request_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)

标量和字符串

除了使用瞬时向量表达式和区间向量表达式以外,PromQL 还直接支持用户使用标量(Scalar)和字符串(String)。

标量

标量只有一个数字,没有时序。例如:

10

需要注意的是,当使用表达式 count(http_requests_total),返回的数据类型,依然是瞬时向量。用户可以通过内置函数 scalar() 将单个瞬时向量转换为标量。

字符串

直接使用字符串,作为 PromQL 表达式,则会直接返回字符串。

"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`

子查询

子查询允许您在给定范围和分辨率内运行瞬时查询。子查询的结果是范围向量。

语法:<instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]<resolution> 可缺省。

查询优化

陈旧性

运行查询时,选择采样数据(独立于实际当前时间序列)的时间戳。这主要是为了支持聚合(总和,平均等)这样的情况,其中多个聚合时间序列在时间上不完全对齐。由于它们的独立性,Prometheus 需要在每个相关时间序列的时间戳上分配值。它只需在此时间戳之前采用最新的样本即可。

如果目标抓取或规则评估不再返回先前存在的时间序列的样本,则该时间序列将被标记为陈旧。如果目标被移除,之前很快就会将其先前返回的时间序列标记为陈旧。如果在时间序列标记为过时后在采样时间戳处计算查询,则不会为该时间系列返回任何值。如果随后在该时间序列中摄取新样本,它们将照常返回。

如果在采样时间戳前 5 分钟未找到任何样本(默认情况下),则此时间点不返回该时间序列的值。这实际上意味着时间序列在其最新收集的样本超过 5 分钟或者标记为陈旧之后从图表“消失”。对于在其刮擦中包含时间戳的时间序列,不会标记陈旧性。在这种情况下,仅应用 5 分钟的阈值。

避免慢查询和重载

如果查询需要对大量数据进行操作,则绘制图表可能会超时或使服务器或浏览器过载。因此,在构建对未知数据的查询时,始终在 Prometheus 表达式浏览器的表格视图中开始构建查询,直到结果集看起来合理(最多数百个,而不是数千个时间序列)。只有在您充分过滤或汇总数据后,才能切换到图表模式。如果表达式仍然需要很长时间来绘制图形,请通过记录规则 预先记录它。

这与 Prometheus 的查询语言尤其相关,其中像 api_http_requests_total 这样的简单 metric 选择器可以扩展到具有不同标签的数千个时间序列。还要注意,即使输出只是少量的时间序列,聚合在许多时间序列上的表达式也会在服务器上产生负载。这类似于在关系数据库中对列的所有值求和的速度很慢,即使输出值只是一个数字。

上一页
下一页