0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PromQL查询的整体结构及类型检查

马哥Linux运维 来源:Prometheus中文社区 作者:Prometheus中文社区 2022-05-25 09:59 次阅读

本文让我们一起来看看PromQL查询解析。虽然PromQL有操作符、函数、选择器等,但我们无需被本篇文章中的这些细节所困扰。让我们来看看查询的总体性质:PromQL查询是如何结构化和类型化的?随着时间的推移它们是如何评估的?

让我们来看一下PromQL的查询结构。PromQL有操作符、函数、选择器等等,但是我们不要被本篇文章中的细节所困扰。相反,让我们看看查询的整体:PromQL查询是如何构造和输入的,以及随着时间的推移它们是如何被评估的?

这篇博客文章将假设您对PromQL查询和Prometheus数据模型有大概粗略的了解。

让我们开始吧!

1.PromQL是一种嵌套的函数式语言

不像SQL或其他一些更倾向于命令式的查询语言(SELECT * FROM...),PromQL是一种嵌套的函数式语言。这意味着您将所寻找的数据描述为一组嵌套表达式,每个表达式都计算出一个中间值(没有副作用)。每个中间值都用作它周围表达式的参数或操作数,而查询的最外层表达式表示您在表、图或类似用例中看到的最终返回值。

查询示例如下所示:

#Rootofthequery,finalresult,approximatesaquantile.
histogram_quantile(
#1stargumenttohistogram_quantile(),thetargetquantile.
0.9,
#2ndargumenttohistogram_quantile(),anaggregatedhistogram.
sumby(le,method,path)(
#Argumenttosum(),theper-secondincreaseofahistogramover5m.
rate(
#Argumenttorate(),therawhistogramseriesoverthelast5m.
demo_api_request_duration_seconds_bucket{job="demo"}[5m]
)
)
)

PromQL表达式不仅是整个查询,而且是查询的任何嵌套部分(如上面的rate(…)部分),可以单独作为查询运行。在上面的例子中,每个注释行代表一个表达式。

当你在PromLabs的PromLens查询可视化工具中分析相同的查询时,包含子表达式的嵌套表达式结构会变得特别清晰:

67d6e186-db67-11ec-ba43-dac502259ad0.png

在PromLens中,您可以单击每个树节点来分别评估其子表达式,以了解您在嵌套表达式树的每个部分中处理的数据。

2.输入的表达式,可能不像你想的那样

Prometheus中有两个“类型”的概念:

  • 由抓取目标所报告的度量类型:计数器、仪表、直方图、摘要或无类型。

  • PromQL表达式的类型:字符串、标量、瞬时向量或范围向量。

PromQL完全忽略度量类型,只关心表达式类型:每个表达式都有一个类型,每个函数、操作符或其他类型的操作都要求其参数是某种表达式类型。例如,rate()函数要求其参数是一个范围向量,但rate()本身的计算结果是一个瞬时向量。因此,rate()的结果只能用于期望瞬时向量的地方。

PromQL中可能的表达式类型有:

  • 字符串:类似 "I am a string!". 这些只作为某些函数(如label_join())的参数出现,在PromQL中并不常用。

  • 标量:没有标注尺寸的单个数值,如 1.234。您将看到这些函数的数值参数,如histogram_quantile(0.9,…)或topk(3,…),以及算术运算。

  • 瞬时向量:一组带标签的时间序列,每个序列有一个样本,所有样本都有相同的时间戳。瞬时向量可以直接来自TSDB时间序列选择器,如node_cpu_seconds_total,也可以来自返回它们的任何函数或其他转换。

node_cpu_seconds_total{cpu="0",mode="idle"}→19165078.75@timestamp_1
node_cpu_seconds_total{cpu="0",mode="system"}→381598.72@timestamp_1
node_cpu_seconds_total{cpu="0",mode="user"}→23211630.97@timestamp_1

  • 范围向量:一组带标签的时间序列,每个序列都有一段时间的样本范围。在PromQL中只有两种方法产生范围向量:在查询中使用文字范围向量选择器(如node_cpu_seconds_total[5m]),或者使用子查询(如[5m:10s])。当您想要聚合指定时间窗口内的一系列行为时,范围向量非常有用,就像您使用rate(node_cpu_seconds_total[5m])计算node_cpu_seconds_total在过去5分钟内的平均每秒增长率一样。

node_cpu_seconds_total{cpu="0",mode="idle"}→19165078.75@timestamp_1,19165136.3@timestamp_2,19165167.72@timestamp_3
node_cpu_seconds_total{cpu="0",mode="system"}→381598.72@timestamp_1,381599.98@timestamp_2,381600.58@timestamp_3
node_cpu_seconds_total{cpu="0",mode="user"}→23211630.97@timestamp_1,23211711.34@timestamp_2,23211748.64@timestamp_3

但是指标类型呢?如果您已经使用过PromQL,您可能知道某些函数只适用于特定类型的指标!例如,histogram_quantile()函数只适用于直方图指标,rate()只适用于计数器指标,而deriv()只适用于仪表。但是PromQL实际上并不检查您是否传入了正确类型的指标——这些函数通常会顺利地运行,并为错误类型的输入指标返回一些无意义的东西,并且由用户决定是否传入符合某些假设的时间序列(比如在直方图的情况下有一个敏感的le标签,或者在计数器的情况下单调增加)。然而,将来我们很可能会看到像PromLens这样的用户界面试图警告你,如果你把一个不兼容的指标类型传递给一个函数。

3.时间是怎么进来的?范围和即时查询!

您可能已经注意到,PromQL查询中对时间的唯一引用是相对引用(例如[5m],向后看5分钟)。那么,如何指定绝对图形时间范围,或者在表中显示查询结果的时间戳呢?在PromQL中,这样的时间参数与表达式分开发送给Prometheus查询API,确切的时间参数取决于您发送的查询类型。Prometheus有两种类型的PromQL查询:即时查询和范围查询。

3.1即时查询

即时查询用于类似表格的视图,在这些视图中,您希望显示PromQL查询在单个时间点的结果。

即时查询的参数包括:

  • PromQL表达式。

  • 评估时间戳

表达式在计算时间戳时进行计算,查询中的任何数据选择器都可以选择从该时间戳回溯到过去的数据(foo[1h]选择foo系列的最后一个小时的数据),但不能选择未来的数据(foo[-1h]是无效的PromQL)。访问过去数据的窗口通常有助于计算一段时间内的比率或平均值等总量。

即时查询可以返回任何有效的PromQL表达式类型(字符串、标量、即时和范围瞬时和范围向量)。

例如即时查询:

让我们看一个即时查询的例子,看看它是如何工作的。想象一下使用表达式http_requests_total查询给定的时间戳数据。http_requests_total是一个瞬时向量选择器,它使用指标名称http_requests_total为任何时间序列选择最新的样本。更具体地说,相对于评估时间戳,“latest”意味着“最多5分钟以前的并且不是陈旧的”。因此,该选择器将只为在评估时间戳之前最多5分钟有一个样本的序列产生一个结果,并且评估时间戳之前的最后一个样本不是一个陈旧的标记(一种将序列标记为在Prometheus TSDB中的某个时间终止的显式方法)。

如果我们在有最近样本的时间戳上运行此查询,结果将包含两个序列,每个序列只有一个样本:

681e84dc-db67-11ec-ba43-dac502259ad0.png

注意,每个返回样本的输出时间戳不再是原始样本时间戳,而是被设置为评估时间戳。

想象一下,在一个时间戳上执行同样的查询,在该时间戳之前有>5m的数据间隔:

6842c8e2-db67-11ec-ba43-dac502259ad0.png

在这种情况下,查询将返回一个空结果,因为所有匹配的样本都太旧而无法包含。

3.2范围查询

范围查询主要用于图形,其中您希望显示给定时间范围内的PromQL表达式。范围查询的工作方式完全类似于许多完全独立的即时查询,这些查询在给定时间范围内的后续时间步骤中进行评估。当然,这是经过高度优化的,在这种情况下,Prometheus实际上并没有运行很多独立的即时查询。

范围查询包含以下参数:

  • PromQL表达式。

  • 开始时间。

  • 结束时间。

  • 解析步骤。

在开始时间和结束时间之间的每个解析步骤对表达式求值后,单独求值的时间片被拼接到单个范围向量中。范围查询允许传入瞬时向量类型或标量类型的表达式,但总是返回一个范围向量(标量或瞬时向量在一段时间内计算的结果)。

范围查询示例:

如果我们将上面的示例表达式评估为一个范围查询,它将如下所示:

68692a78-db67-11ec-ba43-dac502259ad0.png

请注意,每个评估步骤的行为完全类似于独立的即时查询,并且每个独立的即时查询对查询的整体范围没有概念。这种情况下的最终结果将是一个范围向量,它包含一个时间范围内两个选定序列的样本,但也包含某些时间步长的序列数据中的间隙。

最后

希望这篇博客文章让您对PromQL查询的整体结构、正在进行的类型检查(或缺少的类型检查)以及查询的解析评估有了更好的了解。

ABOUT——关于Prometheus中文社区

Prometheus中文社区已与Prometheus原厂官方达成合作,通过官方的支持希望能为您带来以下服务:

资讯分享Prometheus中文社区旨在为Prometheus开发者们提供最新的官方资讯以及专业知识,为开发者们分享第一手的Prometheus信息

技术交流加入社区交流分享经验,让社区大佬帮您解决身边的实际问题;提出您的见解、技术心得,交流专业资源讨论技术话题。打造一个开发者们交流技术干货的信息平台。

专业服务现在我们已与Prometheus达成合作,携手联合创始人Julius Volz及其专业团队,旨在为您提供更优质、更具性价比的监控设置咨询服务。了解更多Prometheus内容或需要更多专业服务请联系我们!

原文标题:PromQL查询剖析

文章出处:【微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3864

    浏览量

    61304
  • 查询
    +关注

    关注

    15

    文章

    34

    浏览量

    13785
  • Prometheus
    +关注

    关注

    0

    文章

    26

    浏览量

    1676

原文标题:PromQL查询剖析

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    类型检查:时常被忽略的编译器组件

    大家好,我是朱子润,很高兴为大家带来本次有关类型检查与推导的分享。
    发表于 11-14 14:24 572次阅读

    树莓派整体结构与功能模块

    0、整体结构与功能模块1、树莓派刷写镜像2、无显示器配置wifi并开启ssh3、配置samba4、配置STM32控制板5、底盘结构
    发表于 08-11 07:03

    如何去实现单片机系统中结构体数据类型的存储和读取呢

    这个结构类型的存储空间为N个字节。注意:关于结构整体占用存储空间的大小,并不是其中每个成员变量的长度简单的
    发表于 01-26 07:42

    PCB板的整体布局与印刷结构

    PCB板的整体布局与印刷结构内容有怎样选定电路的排版方向,整体布局,面板外元和接线草图,印制板尺寸草图等内容。
    发表于 09-30 12:33 0次下载

    色带结构类型/色带颜色

    色带结构类型/色带颜色           结构类型指的是色带的组
    发表于 12-28 16:15 1335次阅读

    拓扑结构,拓扑结构有哪些类型?

    拓扑结构,计算机网络的拓扑结构有哪些类型? 计算机网络的拓扑结构 是指网络中各个站点相互连接
    发表于 03-22 11:20 1.3w次阅读

    C语言教程之检查字符类型

    C语言教程之检查字符类型,很好的C语言资料,快来学习吧。
    发表于 04-25 09:38 0次下载

    元器件封装类型查询

    元器件封装类型查询
    发表于 10-23 09:14 0次下载

    结构查询语言SQL的使用详解

    本章讲授结构化査询语言SQL,它是关系数据库的标准语言,具有强大的功能。在它的四大功能中,重点介绍数据查询功能。
    发表于 07-06 17:08 0次下载
    <b class='flag-5'>结构</b>化<b class='flag-5'>查询</b>语言SQL的使用详解

    Struct结构数据类型

    Struct类型是一种由多个不同数据类型元素组成的数据结构,其元素可以是基本数据类型,也可以是Struct、数组等复杂数据类型以及PLC数据
    的头像 发表于 07-25 17:02 2430次阅读

    STRUC:定义结构类型

    部件: 组件的名称。在结构类型之内只允许进行一次。只在栏拥有 CHAR 类型且是一维时,才允许将其用作结构类型的组件。为此,在
    的头像 发表于 08-03 15:10 1585次阅读

    C语言如何定义结构类型变量

    在定义了结构体变量后,系统会为之分配内存单元。根据结构类型中包含的成员情况,在Visual C++中占63个字节。 * 这种声明方式是声明类型和定义变量分离,在声明
    的头像 发表于 03-10 15:35 866次阅读

    PromQL查询剖析

    不像SQL或其他一些更倾向于命令式的查询语言(SELECT * FROM...),PromQL是一种嵌套的函数式语言。这意味着您将所寻找的数据描述为一组嵌套表达式,每个表达式都计算出一个中间值(没有副作用)。
    的头像 发表于 03-31 11:39 511次阅读

    KUKA变成STRUC:定义结构类型

    部件: 组件的名称。在结构类型之内只允许进行一次。只在栏拥有 CHAR 类型且是一维时,才允许将其用作结构类型的组件。为此,在
    的头像 发表于 04-14 11:41 802次阅读

    修改查询将clob转成字符类型

    在进行Oracle数据库查询时,我们经常会遇到clob类型的数据,这是一种用于存储大型字符数据的数据类型。在一些情况下,我们可能需要将clob类型的数据转换为字符
    的头像 发表于 11-21 11:31 333次阅读