网站建设几个要素,设计癖官网,玉树市公司网站建设,和凡科网类似的网站前言#xff1a;
PromQL是Prometheus的查询语言#xff0c;用于从Prometheus服务器中获取和处理时间序列数据。它采用了类似SQL的语法#xff0c;但专门设计用于处理指标数据。PromQL具有灵活的查询能力#xff0c;可以对指标进行过滤、聚合、计算和变换#xff0c;以生成…前言
PromQL是Prometheus的查询语言用于从Prometheus服务器中获取和处理时间序列数据。它采用了类似SQL的语法但专门设计用于处理指标数据。PromQL具有灵活的查询能力可以对指标进行过滤、聚合、计算和变换以生成有意义的监控数据。
一 PromQL 简介
PromQLPrometheus Query Language是 Prometheus 内置的数据查询语言。支持用户进行实时的数据查询及聚合操作。
1 Prometheus 基于指标名称metrics name以及附属的标签集labelset唯一定义一条时间序列
●指标名称代表着监控目标上某类可测量属性的基本特征标识 ●标签则是这个基本特征上再次细分的多个可测量维度
2 基于 PromQL 表达式用户可以针对指定的特征及其细分的纬度进行过滤、聚合、统计等运算从而产生期望的计算结果
●PromQL 使用表达式expression来表述查询需求 ●根据其使用的指标和标签以及时间范围表达式的查询请求可灵活地覆盖在一个或多个时间序列的一定范围内的样本之上甚至是只包含单个时间序列的单个样本
3 Prometheus 数据模型
Prometheus 中每个时间序列都由指标名称Metric Name和标签Label来唯一标识 格式为metric_name{label_namelabel_value, ...}
●指标名称通常用于描述系统上要测定的某个特征 例如prometheus_http_requests_total 表示接收到的 HTTP 请求总数
●标签键值型数据附加在指标名称之上从而让指标能够支持多纬度特征可选项 例如prometheus_http_requests_total{code200} 和 prometheus_http_requests_total{code302} 代表着两个不同的时间序列 ●双下划线的标签例如 __address__ 是 Prometheus 系统默认标签是不会显示在 /metrics 页面里面的 ●系统默认标签在 target 页面中也是不显示的需要鼠标放到 label 字段上才会显示。 ●常见的系统默认标签 __address__ 当前 target 实例的套接字地址 host:port __scheme__ 采集当前 target 上指标数据时使用的协议http 或 https __metrics_path__ 采集当前 target 上的指标数据时使用 URI 路径默认为 /metrics __param_name 传递的 URL 参数中第一个名称为 name 的参数的值 __name__ : 此标签是标识指标名称的预留标签能够使用标签选择器对指标名称进行过滤
4 指标名称及标签使用注意事项
●指标名称和标签的特定组合代表着一个时间序列指标名称相同但标签不同的组合分别代表着不同的时间序列不同的指标名称自然更是代表着不同的时间序列
●PromQL支持基于定义的指标维度进行过滤和聚合更改任何标签值包括添加或删除标签都会创建一个新的时间序列应该尽可能地保持标签的稳定性否则则很可能创建新的时间序列更甚者会生成一个动态的数据环境并使得监控的数据源难以跟踪从而导致建立在该指标之上的图形、告警及记录规则变得无效
5 样本数据格式
Prometheus 的每个数据样本由两部分组成 ●毫秒精度的时间戳 ●float64 格式的数据
prometheus_http_requests_total{code200, handler/targets, instancelocalhost:9090, jobprometheus} 1434317560885 28
prometheus_http_requests_total{code200, handler/targets, instancelocalhost:9090, jobprometheus} 1434317561483 35
prometheus_http_requests_total{code200, handler/targets, instancelocalhost:9090, jobprometheus} 1434317562589 42
prometheus_http_requests_total{code200, handler/targets, instancelocalhost:9090, jobprometheus} 1434317563654 50
| || | | | |---------- 指标名称 -------- ------------------------ 标签 --------------------------------------------- -- 时间戳 -- 样本值
二 PromQL 的数据类型
1 PromQL 的表达式中支持 4 种数据类型
●即时向量 (Instant vector): 特定或全部的时间序列集合上具有相同时间戳的一组样本值 ●区间向量 (Range vector): 特定或全部的时间序列集合上在指定的同一时间范围内的所有样本值 ●标量数据 (Scalar): 一个浮点型的数据值 ●字符串 (String): 一个字符串支持使用单引号、双引号进行引用
2 时间序列选择器Time series Selectors
PromQL 的查询操作可能需要针对若干个时间序列上的样本数据进行挑选出目标时间序列是构建表达式时最为关键的一步
用户可使用向量选择器表达式来挑选出给定指标名称下的所有时间序列或部分时间序列的即时样本值或至过去某个时间范围内的样本值前者称为瞬时向量选择器后者称为区间向量选择器。
3 即时向量选择器Instant Vector Selectors
瞬时向量选择器可以返回 0 个、1 个或多个时间序列上在给定时间戳instant上的各自的一个样本。
① 即时向量选择器由两部分组成
◆指标名称用于限定特定指标下的时间序列即负责过滤指标可选 ◆标签选择器用于过滤时间序列上的标签定义在 {} 之中可选
② 定义即时向量选择器时以上两个部分应该至少给出一个因此存在以下三种组合
◆仅给定指标名称或在标签名称上使用了空值的标签选择器返回给定的指标下的所有时间序列各自的即时样本 例如prometheus_http_requests_total 和 prometheus_http_requests_total{} 的功能相同都是用于返回这个指标下各时间序列的即时样本
◆仅给定标签选择器返回所有符合给定的标签选择器的所有时间序列上的即时样本 例如{code200, jobprometheus} 这样的时间序列可能会有着不同的指标名称
◆指标名称和标签选择器的组合返回给定的指标下的且符合给定的标签过滤器的所有时间序列上的即时样本 例如prometheus_http_requests_total{code200, jobprometheus}用于返回这个指标 code 为 200 并且 job 为 prometheus 的时间序列的即时样本
匹配器
#标签选择器用于定义标签过滤条件目前支持如下4种匹配操作符 完全相等 ! 不相等 ~ 正则表达式匹配 !~ 正则表达式不匹配
注意事项
◆匹配到空标签值的标签选择器时所有未定义该标签的时间序列同样符合条件 例如prometheus_http_requests_total{handler }则该指标名称上所有未使用该标签handler的时间序列也符合条件
◆正则表达式将执行完全锚定机制它需要匹配指定的标签的整个值
◆向量选择器至少要包含一个指标名称或者至少有一个不会匹配到空字符串的标签选择器 例如{ job} 为非法的向量选择器
◆使用 __name__ 做为标签名称还能够对指标名称进行过滤 例如{__name__~.*http_requests_total} 能够匹配所有以 http_requests_total 为后缀的所有指标
4 区间向量选择器Range Vector Selectors
区间向量选择器可以返回 0 个、1 个或多个时间序列上在给定时间范值围内的各自的一组样本。 区间向量选择器的不同之处在于需要通过在瞬时向量选择器表达式后面添加包含在 [] 里的时长来表达需在时间时序上返回的样本所处的时间范围。
时间范围以当前时间为基准时间点指向过去一个特定的时间长度例如[5m] 是指过去 5 分钟之内。 ◆可用的时间单位有 ms毫秒、s秒、m分钟、h小时、d天、w周和 y年 ◆必须使用整数时间且能够将多个不同级别的单位进行串联组合以时间单位由大到小为顺序例如 1h30m但不能使用 1.5h
偏移向量选择器
前面介绍的选择器默认都是以当前时间为基准时间偏移修饰器用来调整基准时间使其往前偏移一段时间。偏移修饰器紧跟在选择器后面使用关键字 offset 来指定要偏移的量。 例如prometheus_http_requests_total offset 5m 表示获取以 prometheus_http_requests_total 为指标名称的所有时间序列在过去 5 分钟之时的即时样本 prometheus_http_requests_total[5m] offset 1d 表示获取距此刻 1 天时间之前的 5 分钟之内的所有样本
5 向量表达式使用要点
●表达式的返回值类型亦是即时向量、范围向量、标题或字符串4种数据类型其中之一但是有些使用场景要求表达式返回值必须满足特定的条件例如 1需要将返回值绘制成图形时仅支持即时向量类型的数据 2对于诸如 rate、irate 之类的速率函数来说其要求使用的却又必须是区间向量型的数据
●由于区间向量选择器的返回的是区间向量型数据它不能用于表达式浏览器中图形绘制功能
●区间向量选择器通常会结合速率类的函数 rate、irate 一同使用
三 PromQL 的指标类型 PromQL 有四个指标类型
●Counter 计数器用于保存单调递增型的数据例如站点访问次数等。数据单调递增不支持减少不能为负值重启进程后会被重置回 0 ●Gauge 仪表盘用于存储有着起伏特征的指标数据例如内存空闲大小等。数据可变大可变小重启进程后会被重置 ●Histogram 累积直方图将时间范围内的数据划分成不同的时间段并各自评估其样本个数及样本值之和因而可计算出分位数 ◆可用于分析因异常值而引起的平均值过大的问题 ◆分位数计算要使用专用的 histogram_quantile 函数 ●Summary 类似于 Histogram但会在客户端直接计算并上报分位数
1 Counter
通常Counter 的总数并没有直接作用而是需要借助于 rate、topk、increase 和 irate 等函数来生成样本数据的变化状况增长率/变化率 ●topk(3, prometheus_http_requests_total)获取该指标下 http 请求总数排名前 3 的时间序列
●rate(prometheus_http_requests_total[1h]) 获取 1 小内该指标下各时间序列上的 http 总请求数的增长速率
●irate(prometheus_http_requests_total[1h]) irate 为高灵敏度函数用于计算指标的瞬时速率基于样本范围内的最后两个样本进行计算相较于 rate 函数来说irate 更适用于短期时间范围内的变化速率分析。
2 Gauge
Gauge 用于存储其值可增可减的指标的样本数据常用于进行求和、取平均值、最小值、最大值等聚合计算 也会经常结合 PromQL 的 delta 和 predict_linear 函数使用 ●delta 函数计算范围向量中每个时间序列元素的第一个值与最后一个值之差从而展示不同时间点上的样本值的差值 例如delta(cpu_temp_celsius{hostnode01}[2h]) 返回该服务器上的CPU温度与2小时之前的差异
●predict_linear 函数可以预测时间序列 v 在 t 秒后的值它通过线性回归的方式对样本数据的变化趋势做出预测 例如predict_linear(node_filesystem_free{jobnode}[2h], 4 * 3600) 基于 2 小时的样本数据来预测主机可用磁盘空间在 4 个小时之后的剩余情况
3 Histogram
对于 Prometheus 来说Histogram 会在一段时间范围内对数据进行采样通常是请求持续时长或响应大小等并将其计入可配置的 bucket存储桶中 后续可通过指定区间筛选样本也可以统计样本总数最后一般将数据展示为直方图。
Prometheus 取值间隔的划分采用的是累积区间间隔机制即每个 bucket 中的样本均包含了其前面所有 bucket 中的样本因而也称为累积直方图。
Histogram 类型的每个指标有一个基础指标名称 basename它会提供多个时间序列 ●basename_sum 所有样本值的总和
●basename_count 总的采样次数它自身本质上是一个 Counter 类型的指标
●basename_bucket{le上边界} 观测桶的上边界即样本统计区间表示样本值小于等于上边界的所有样本数量 basename_bucket{leInf} 最大区间包含所有样本的样本数量
使用 histogram
在大多数情况下人们一般倾向于使用某些量化指标的平均值例如 CPU 的平均使用率、页面的平均响应时间。这种方式的问题很明显以系统 API 调用的平均响应时间为例如果大多数 API 请求都维持在 100ms 的响应时间范围内而个别请求的响应时间需要 5s那么就会导致某些 Web 页面的响应时间落到中位数的情况而这种现象被称为长尾问题。 为了区分是平均的慢还是长尾的慢最简单的方式就是按照请求延迟的范围进行分组。例如统计延迟在 0~10 ms 之间的请求数有多少而 10~20 ms 之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram和Summary都是为了能够解决这样问题的存在通过 Histogram 和 Summary 类型的监控指标我们可以快速了解监控样本的分布情况。
http 请求响应时间 0.005 秒 的请求次数为 10
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.005} 10http 请求响应时间 0.01 秒 的请求次数为 15
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.01} 15http 请求响应时间 0.025 秒 的请求次数为 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.025} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.05} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.075} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.1} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.25} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.5} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.75} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le1.0} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le2.5} 18
prometheus_http_request_duration_seconds_bucket{handler/metrics,le5.0} 20
prometheus_http_request_duration_seconds_bucket{handler/metrics,le7.5} 20
prometheus_http_request_duration_seconds_bucket{handler/metrics,leInf} 20所有样本值的大小总和命名为 basename_sum
prometheus_http_request_duration_seconds_sum{handler/metrics} 10.107670803000001样本总数命名为 basename_count 效果与 basename_bucket{leInf} 相同
prometheus_http_request_duration_seconds_count{handler/metrics} 20注意
bucket 可以理解为是对数据指标值域的一个划分划分的依据应该基于数据值的分布。注意后面的样本是包含前面的样本假设 prometheus_http_request_duration_seconds_bucket{...,le0.01} 的值为 10而 prometheus_http_request_duration_seconds_bucket{...,le0.05} 的值为 30 那么意味着这 30 个样本中有 10 个是小于 0.01s 的其余 20 个采样点的响应时间是介于 0.01s 和 0.05s 之间的。
累积间隔机制生成的样本数据需要额外使用内置的 histogram_quantile 函数即可根据 Histogram 指标来计算相应的分位数quantile即某个 bucket 的样本数在所有样本数中占据的比例。 ●histogram_quantile 函数在计算分位数时会假定每个区间内的样本满足线性分布状态因而它的结果仅是一个预估值并不完全准确 ●预估的准确度取决于bucket区间划分的粒度粒度越大准确度越低
例如假设 http 请求响应时间的样本的 9 分位数quantile0.9的上边界为 0.01即表示小于等于 0.01 的样本值的数量占总体样本值的 90% histogram_quantile(prometheus_http_request_duration_seconds_bucket{handler/metrics,le0.01}) 0.9
4 Summary
Histogram 在客户端仅是简单的桶划分和分桶计数分位数计算由 Prometheus Server 基于样本数据进行估算因而其结果未必准确甚至不合理的 bucket 划分会导致较大的误差。
Summary 是一种类似于 Histogram 的指标类型但它在客户端于一段时间内默认为 10 分钟的每个采样点进行统计计算并存储了分位数数值Server 端直接抓取相应值即可。
对于每个指标Summary 以指标名称 basename 为前缀生成如下几个指标序列 ●basename_sum 统计所有样本值之和
●basename_count 统计所有样本总数
●basename{quantilex} 统计样本值的分位数分布情况分位数范围0 ≤ x ≤ 1
示例
prometheus_tsdb_wal_fsync_duration_seconds{quantile0.5} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile0.9} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile0.99} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216
从上面的样本中可以得知当前Promtheus Server进行 wal_fsync 操作的总次数为 216 次耗时 2.888716127000002s。 其中中位数quantile0.5的耗时为 0.012352463s9分位数quantile0.9的耗时为0.014458005s。
#Histogram 与 Summary 的异同 它们都包含了 basename_sum 和 basename_count 指标Histogram 需要通过 basename_bucket 来计算分位数而 Summary 则直接存储了分位数的值。
四 Prometheus 的聚合函数
一般说来单个指标的价值不大监控场景中往往需要联合并可视化一组指标这种联合机制即是指“聚合”操作例如将计数、求和、平均值、分位数、标准差及方差等统计函数应用于时间序列的样本之上生成具有统计学意义的结果等。
对查询结果事先按照某种分类机制进行分组group by并将查询结果按组进行聚合计算也是较为常见的需求例如分组统计、分组求平均值、分组求和等。
Prometheus 的聚合操作由聚合函数针对一组值进行计算并返回值作为结果。
1 Prometheus 内置提供的 11 个聚合函数也称为聚合运算符
●sum()对样本值求和 ●min() 求取样本值中的最小者 ●max() 求取样本值中的最大者 ●avg() 对样本值求平均值 ●count() 对分组内的时间序列进行数量统计 ●stddev() 对样本值求标准差以帮助用户了解数据的波动大小或称之为波动程度 ●stdvar() 对样本值求方差它是求取标准差过程中的中间状态 ●topk() 逆序返回分组内的样本值最大的前 k 个时间序列及其值即最大的 k 个样本值 ●bottomk() 顺序返回分组内的样本值最小的前 k 个时间序列及其值即最小的 k 个样本值 ●quantile() 分位数用于评估数据的分布状态该函数会返回分组内指定的分位数的值即数值落在小于等于指定的分位区间的比例 ●count_values() 对分组内的时间序列的样本值进行数量统计即等于某值的样本个数
2 PromQL 的聚合表达式
PromQL 中的聚合操作语法格式可采用如下面两种格式之一 ● 聚合函数(向量表达式) by|without (标签) ● 聚合函数 by|without (标签) (向量表达式)
分组聚合先分组、后聚合 by 仅使用by子句中指定的标签进行聚合结果向量中出现但未被 by 指定的标签则会被忽略 为了保留上下文信息使用 by 子句时需要显式指定其结果中原本出现的 job、instance 等一类的标签。
without从结果向量中删除由 without 指定的标签未指定的那部分标签则用作分组标准
3 示例
1每台主机 CPU 在最近 5 分钟内的平均使用率 (1 - avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance)) * 100
2查询 1 分钟的 load average 的时间序列是否超过主机 CPU 数量 2 倍 node_load1 on (instance) 2 * count (node_cpu_seconds_total{modeidle}) by (instance)
3计算主机内存使用率 可用内存空间空闲内存、buffer、cache 指标之和 node_memory_MemFree_bytes node_memory_Buffers_bytes node_memory_Cached_bytes
已用内存空间总内存空间减去可用空间 node_memory_MemTotal_bytes - (node_memory_MemFree_bytes node_memory_Buffers_bytes node_memory_Cached_bytes)
使用率已用空间除以总空间 (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes node_memory_Buffers_bytes node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100
4计算所有 node 节点所有容器总计内存 sum by (instance) (container_memory_usage_bytes{instance~node*})/1024/1024/1024
5计算 node01 节点最近 1m 所有容器 cpu 使用率 sum (rate(container_cpu_usage_seconds_total{instancenode01}[1m])) / sum (machine_cpu_cores{instancenode01}) * 100 #container_cpu_usage_seconds_total 代表容器占用CPU的时间总和
6计算最近 5m 每个容器 cpu 使用情况变化率 sum (rate(container_cpu_usage_seconds_total[5m])) by (container_name)
7查询 K8S 集群中最近 1m 每个 Pod 的 CPU 使用情况变化率 sum (rate(container_cpu_usage_seconds_total{image!, pod_name!}[1m])) by (pod_name) #由于查询到的数据都是容器相关的所以最好按照 Pod 分组聚合
五 部署 Alertmanager 发送告警
Prometheus 对指标的收集、存储与告警能力分属于 Prometheus Server 和 AlertManager 两个独立的组件前者仅负责定义告警规则生成告警通知 具体的告警操作则由后者完成。
Alertmanager 负责处理由 Prometheus Server 发来的告警通知Alertmanager对告警通知进行分组、去重后根据路由规则将其路由到不同的receiver如 Email、钉钉或企业微信等。
除了基本的告警通知能力外Altermanager还支持对告警进行去重、分组、抑制、静默和路由等功能 ●分组Grouping将相似告警合并为单个告警通知的机制在系统因大面积故障而触发告警潮时分组机制能避免用户被大量的告警噪声淹没进而导致关键信息的隐没
●抑制Inhibition系统中某个组件或服务故障而触发告警通知后那些依赖于该组件或服务的其它组件或服务可能也会因此而触发告警抑制便是避免类似的级联告警的一种特性从而让用户能将精力集中于真正的故障所在
●静默Silent是指在一个特定的时间窗口内即便接收到告警通知Alertmanager也不会真正向用户发送告警信息的行为通常在系统例行维护期间需要激活告警系统的静默特性
●路由route用于配置Alertmanager如何处理传入的特定类型的告警通知其基本逻辑是根据路由匹配规则的匹配结果来确定处理当前告警通知的路径和行为
部署 Alertmanager