自学内容网 自学内容网

Prometheus之PromQl

//什么是PromQL PromQL(Prometheus Query Language)是 Prometheus 内置的数据查询语言, 语言表现力很丰富,内置函数也很多。支持用户进行实时的数据查询及聚合操作。

#匹配标签值时可以是等于,也可以使用正则表达式。总共有下面几种匹配操作符: = :完全相等 != : 不相等 =~ : 正则表达式匹配 !~ : 正则表达式不匹配

PromQL常用的通配符: . 任意一个字符 .* 多个任意字符 .+ 一个或者多个任意字符

PromQL支持的所有数学运算符如下所示:

  • (加法)

  • (减法)

  • (乘法)

/ (除法)

% (求余)

^ (幂运算)

Prometheus 数据模型 Prometheus 中,每个时间序列都由指标名称(Metric Name)和标签(Label)来唯一标识 格式为:<metric_name>{<label_name>=<label_value>, ...}

●指标名称:通常用于描述系统上要测定的某个特征 例如,prometheus_http_requests_total 表示接收到的 HTTP 请求总数

●标签:键值型数据,附加在指标名称之上,从而让指标能够支持多纬度特征;可选项 例如,prometheus_http_requests_total{code="200"} 和 prometheus_http_requests_total{code="302"} 代表着两个不同的时间序列

●双下划线的标签(例如 address )是 Prometheus 系统默认标签,是不会显示在 /metrics 页面里面的;

●系统默认标签在 target 页面中也是不显示的,需要鼠标放到 label 字段上才会显示。

node_cpu_seconds_total{mode="iowait"} 是一个 PromQL 查询,用于选择关于 CPU iowait 模式的时间序列。 这个查询的目标是选择 node_cpu_seconds_total 这个指标中 mode 标签为 "iowait" 的时间序列。

node_cpu_seconds_total 是一个指标名称,代表了 CPU 时间的总数,具体到不同的 CPU 模式。 {mode="iowait"} 是一个标签选择器,过滤出具有 mode 标签且值为 "iowait" 的时间序列。 所以,查询 node_cpu_seconds_total{mode="iowait"} 返回的是所有与 iowait 模式相关的 CPU 时间序列。 这些时间序列记录了在 iowait 模式下的 CPU 时间的累计值。

每个时间序列包含有关特定 CPU 实例和 iowait 模式的信息。例如, node_cpu_seconds_total{mode="iowait", cpu="cpu0"} 表示了 CPU0 的 iowait 模式下的累计时间。

//数据类型 PromQL 表达式计算出来的值有以下几种类型: ●瞬时向量 (Instant vector): 一组时序,每个时序只有一个采样值 ●区间向量 (Range vector): 一组时序,每个时序包含一段时间内的多个采样值 ●标量数据 (Scalar): 一个浮点数 ●字符串 (String): 一个字符串

//瞬时向量选择器 瞬时向量选择器用来选择一组时序在某个采样点的采样值。最简单的情况就是指定一个度量指标, 选择出所有属于该度量指标的时序的当前采样值。 比如下面的表达式: node_cpu_seconds_total node_cpu_seconds_total{mode="iowait",cpu="0"}

然后可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。 比如下面的表达式筛选出了 job 为 kubernetes-apiservers, 并且 resource 为 pod 的时序: node_cpu_seconds_total{mode="iowait",cpu="0"}

#下面的表达式筛选出了 container 是 kube-scheduler 或 kube-proxy 或 kube-apiserver 的时序数据 container_processes{container=~"kube-scheduler|kube-proxy|kube-apiserver"}

//区间向量选择器 区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。 可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。 比如下面的表达式选出了所有度量指标为 apiserver_request_total 且 resource 是 pod 的时序在过去 1 分钟的采样值: rate(node_cpu_seconds_total{mode="iowait"}[5m])

#注:这个不支持 Graph,需要选择 Console,才会看到采集的数据

#时长的单位可以是下面几种之一: s:seconds m:minutes h:hours d:days w:weeks y:years

//偏移向量选择器 前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间, 使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。 #比如下面的表达式选择度量名称为 apiserver_request_total 的所有时序在 5 分钟前的采样值: apiserver_request_total{job="kubernetes-apiserver",resource="pods"} offset 5m

#下面的表达式选择 apiserver_request_total 度量指标在 1小时: apiserver_request_total{job="kubernetes-apiserver",resource="pods"} offset 1h #注:这个不支持 Graph,需要选择 Console,才会看到采集的数据

PromQL 的指标类型 PromQL 有四个指标类型:

●Counter :计数器,用于保存单调递增型的数据;例如站点访问次数等。数据单调递增,不支持减少, 不能为负值,重启进程后,会被重置回 0 ;

●Gauge :仪表盘,用于存储有着起伏特征的指标数据,例如内存空闲大小等。数据可变大,可变小; 重启进程后,会被重置;

●Histogram : 累积直方图,将时间范围内的数据划分成不同的时间段,并各自评估其样本个数及样本值之和,因而可计算出分位数; ◆可用于分析因异常值而引起的平均值过大的问题; ◆分位数计算要使用专用的 histogram_quantile 函数;

●Summary :类似于 Histogram,但会在客户端直接计算并上报分

Counter类型 通常,Counter 的总数并没有直接作用, 而是需要借助于 rate、topk、increase 和 irate 等函数来生成样本数据的变化状况(增长率/变化率): 获取该指标下cpu使用排名前 3 的时间序列 topk(3,node_cpu_seconds_total)

#irate 为高灵敏度函数,用于计算指标的瞬时速率,基于样本范围内的最后两个样本进行计算, 相较于 rate 函数来说,irate 更适用于短期时间范围内的变化速率分析。 rate(container_cpu_system_seconds_total[5m])

irate(container_cpu_system_seconds_total[5m])

increase(container_cpu_system_seconds_total[5m]) increase 函数,它计算一个时间序列在给定时间范围内的增量

Gauge类型 Gauge 用于存储其值可增可减的指标的样本数据,常用于进行求和、取平均值、最小值、最大值等聚合计算; 也会经常结合 PromQL 的 delta 和 predict_linear 函数使用:

#delta 函数计算范围向量中每个时间序列元素的第一个值与最后一个值之差,从而展示不同时间点上的样本值的差值

delta(container_memory_cache{instance="node02"}[5m]) #用于计算在过去 5 分钟内 container_memory_cache 时间序列的增量

#predict_linear 函数可以预测时间序列 v 在 t 秒后的值,它通过线性回归的方式,对样本数据的变化趋势做出预测

predict_linear(node_filesystem_files{instance="node01"}[2h], 4 * 3600) 用于使用线性回归模型预测 node_filesystem_files 指标在过去 2 小时内的变化,并预测未来 4 小时的值。

Histogram类型 对于 Prometheus 来说,Histogram 会在一段时间范围内对数据进行采样(通常是请求持续时长或响应大小等), 并将其计入可配置的 bucket(存储桶)中 ,后续可通过指定区间筛选样本,也可以统计样本总数, 最后一般将数据展示为直方图。

Prometheus 取值间隔的划分采用的是累积区间间隔机制,即每个 bucket 中的样本均包含了其前面所有 bucket 中的样本, 因而也称为累积直方图。

Histogram 类型的每个指标有一个基础指标名称 <basename>,它会提供多个时间序列: ●<basename>_sum :所有样本值的总和

●<basename>_count :总的采样次数,它自身本质上是一个 Counter 类型的指标

node_authorizer_graph_actions_duration_seconds_bucket{instance="192.168.233.91:6443", job="kubernetes-apiserver", le="0.0002", operation="AddPod"} ●<basename>_bucket{le="<上边界>"} :观测桶的上边界,即样本统计区间,表示样本值小于等于上边界的所有样本数量

node_authorizer_graph_actions_duration_seconds_bucket{instance="192.168.233.91:6443", job="kubernetes-apiserver", le="+Inf", operation="AddPV"} <basename>_bucket{le="+Inf"} :最大区间(包含所有样本)的样本数量

#使用 histogram 在大多数情况下人们一般倾向于使用某些量化指标的平均值,例如 CPU 的平均使用率、页面的平均响应时间。 这种方式的问题很明显,以系统 API 调用的平均响应时间为例:如果大多数 API 请求都维持在 100ms 的响应时间范围内, 而个别请求的响应时间需要 5s,那么就会导致某些 Web 页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。 为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。 例如,统计延迟在 0~10 ms 之间的请求数有多少,而 10~20 ms 之间的请求数又有多少。 通过这种方式可以快速分析系统慢的原因。Histogram和Summary都是为了能够解决这样问题的存在, 通过 Histogram 和 Summary 类型的监控指标,我们可以快速了解监控样本的分布情况。

apiserver_current_inqueue_requests{instance="192.168.233.91:6443"} >= 1

container_network_receive_bytes_total{name="k8s_POD_nginx1-654cb56c4-fpf2w_default_f7492be2-f4f6-406f-b0b4-c212117b6328_0"} >= 12

Summary类型 Histogram 在客户端仅是简单的桶划分和分桶计数,分位数计算由 Prometheus Server 基于样本数据进行估算, 因而其结果未必准确,甚至不合理的 bucket 划分会导致较大的误差。 Summary 是一种类似于 Histogram 的指标类型,但它在客户端于一段时间内(默认为 10 分钟)的每个采样点进行统计, 计算并存储了分位数数值,Server 端直接抓取相应值即可。

对于每个指标,Summary 以指标名称 <basename> 为前缀,生成如下几个指标序列: ●<basename>_sum :统计所有样本值之和

●<basename>_count :统计所有样本总数

●<basename>{quantile="x"} :统计样本值的分位数分布情况,分位数范围:0 ≤ x ≤ 1

//聚合操作符 PromQL 的聚合操作符用来将向量里的元素聚合得更少。

总共有下面这些聚合操作符: sum:求和 sum(container_cpu_usage_seconds_total) min:最小值 min(container_cpu_usage_seconds_total) max:最大值 max(container_cpu_usage_seconds_total) avg:平均值 avg(container_cpu_usage_seconds_total) stddev:标准差 stdvar:方差 count:元素个数 count_values:等于某值的元素个数 bottomk:最小的 k 个元素 topk:最大的 k 个元素 quantile:分位数

#计算 master01 节点所有容器总计内存: sum(container_memory_usage_bytes{instance=~"master01"})/1024/1024/1024

#计算 master01 节点最近 1m 所有容器 cpu 使用率: sum (rate (container_cpu_usage_seconds_total{instance=~"master01"}[1m])) / sum (machine_cpu_cores{ instance =~"master01"}) * 100

#计算最近 1m 所有容器 cpu 使用率 sum by (id)(rate (container_cpu_usage_seconds_total{id!="/"}[1m]))

#查询 K8S 集群中最近 1m 每个 Pod 的 CPU 使用率 sum by (name)(rate (container_cpu_usage_seconds_total{image!="", name!=""}[1m]))

(1)每台主机 CPU 在最近 5 分钟内的平均使用率 (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100

(2)查询 1 分钟的 load average 的时间序列是否超过主机 CPU 数量 2 倍 node_load1 > on (instance) 2 * count (node_cpu_seconds_total{mode="idle"}) 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{instance="node01"}[1m])) / sum (machine_cpu_cores{instance="node01"}) * 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 分组聚合


原文地址:https://blog.csdn.net/Alone8046/article/details/142375013

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!