运维进阶-PromQL

1,068 阅读5分钟

官方文档 prometheus.io/docs/promet…

PromQL简介:

Prometheus提供一个函数式的表达式语言PromQL (Prometheus Query Language),可以使用户实时地查找和聚合时间序列数据,表达式计算结果可以在图表中展示,也可以在Prometheus表达式浏览器中以表格形式展示,或者作为数据源, 以HTTP API的方式提供给外部系统使用。

image.png

PromQL查询数据类型

Instant Vector 瞬时向量/瞬时数据

是对目标实例查询到的同一个时间戳的一组时间序列数据(按照时间的推移对数据进存储和展示),每个时间序列包含单个数据样本,

比如node_memory_MemFree_bytes查询的是当前剩余内存(可用内存)就是一个瞬时向量,该表达式的返回值中只会包含该时间序列中的最新的一个样本值,而相应的这样的表达式称之为瞬时向量表达式,

以下是查询node节点可用内存的瞬时向量表达式:

curl 'http://172.30.66.173:9090/api/v1/query' --data 'query=node_memory_MemFree_bytes'

{
	"status": "success",
	"data": {
		"resultType": "vector",
		"result": [{
			"metric": {
				"__name__": "node_memory_MemFree_bytes",
				"instance": "172.30.66.173:9100",
				"job": "node"
			},
			"value": [1670139718.405, "3565387776"]
		}, {
			"metric": {
				"__name__": "node_memory_MemFree_bytes",
				"instance": "172.30.66.174:9100",
				"job": "node"
			},
			"value": [1670139718.405, "6967881728"]
		}]
	}
}

Range Vector:范围向量/范围数据

是指在任何一个时间范围内,抓取的所有度量指标数据.比如最近一天的网卡流量趋势图、或最近5分钟的node节点内容可用字节数等,以下是查询node节点可用内存的范围向量表达式:

curl 'http://172.30.66.173:9090/api/v1/query' --data 'query=node_memory_MemFree_bytes{instance="172.30.66.173:9100"}[5m]' 

{
	"status": "success",
	"data": {
		"resultType": "matrix",
		"result": [{
			"metric": {
				"__name__": "node_memory_MemFree_bytes",
				"instance": "172.30.66.173:9100",
				"job": "node"
			},
			"values": [
				[1670139912.678, "3564736512"],
				[1670139927.678, "3564736512"],
				[1670139942.678, "3564736512"],
				[1670139957.678, "3564736512"],
				[1670139972.678, "3563687936"],
				[1670139987.678, "3564736512"],
				[1670140002.678, "3564736512"],
				[1670140017.678, "3564863488"],
				[1670140032.678, "3565625344"],
				[1670140047.678, "3565371392"],
				[1670140062.678, "3565498368"],
				[1670140077.678, "3565625344"],
				[1670140092.678, "3564990464"],
				[1670140107.678, "3564736512"],
				[1670140122.678, "3564609536"],
				[1670140137.678, "3564609536"],
				[1670140152.678, "3565371392"],
				[1670140167.678, "3565371392"],
				[1670140182.678, "3565625344"],
				[1670140197.678, "3565625344"]
			]
		}]
	}
}

scalar:标量/纯量数据

是一个浮点数类型的数据值,使用node_load1获取到时一个瞬时向量后,在使用prometheus的内置函数scalar()将瞬时向量转换为标量,例如:scalar(sum(node_load1))

curl 'http://172.30.66.173:9090/api/v1/query' --data 'query=scalar(sum(node_load1{instance="172.30.66.173:9100"}))' 

{
	"status": "success",
	"data": {
		"resultType": "scalar",
		"result": [1670140283.697, "0"]
	}
}

string:简单的字符串类型的数据

prometheus指标数据类型:

  • Counter:计数器
  • Gauge:仪表盘
  • Histogram:累积直方图
  • Summary:摘要

Counter:计数器

Counter类型代表一个累积的指标数据,在没有被重启的前提下只增不减(生活中的电表、水表),比如磁盘I/O总数、Nginx/API的请求总数、网卡流经的报文总数等。

http://39.101.77.50:9090/graph?g0.expr=prometheus_http_requests_total&g0.tab=0&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h

image.png

Gauge:仪表盘

Gauge类型代表一个可以任意变化的指标数据,值可以随时增高或减少,如带宽速率、CPU负载、内存利用率、nginx活动连接数等。

http://39.101.77.50:9090/graph?g0.expr=node_load1&g0.tab=0&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h

image.png

Histogram:累积直方图

Histogram会在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等)

假如每分钟产生一个当前的活跃连接数,那么一天24小时*60分钟=1440分钟就会产生1440个数据,查看数据的每间隔的绘图跨度为2小时,

  • 那么2点的柱状图(bucket)会包含0点到2点即两个小时的数据
  • 而4点的柱状图(bucket)则会包含0点到4点的数据
  • 而6点的柱状图(bucket)则会包含0点到6点的数据,

可用于统计从当天零点开始到当前时间的数据统计结果,如http请求成功率、丢包率等,比如ELK的当天访问IP统计

Summary:摘要图

也是一组数据,默认统计选中的指标的最近10分钟内的数据的分位数,可以指定数据统计时间范围,基于分位数(Quantile),亦称分位点,是指用分割点(cut point)将随机数据统计并划分为几个具有相同概率的连续区间,常见的为四分位,四分位数是将数据样本统计后分成四个区间,将范围内的数据进行百分比的占比统计,从0到1,表示是0%~100%,(0%25%,%2550%,50%~75%,75%~100%),利用四分位数,可以快速了解数据的大概统计结果。

PromQL 聚合运算

max() #最大值

计算每个节点的最大的流量值:

max(node_network_receive_bytes_total) by (instance)

http://39.101.77.50:9090/graph?g0.expr=max(node_network_receive_bytes_total)%20by%20(instance)&g0.tab=1&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h

image.png

计算每个节点最近五分钟每个device的最大流量

max(rate(node_network_receive_bytes_total[5m])) by (device)

http://39.101.77.50:9090/graph?g0.expr=max(rate(node_network_receive_bytes_total%5B5m%5D))%20by%20(device)&g0.tab=1&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h

image.png

sum()

求数据值相加的和(总数)

sum(prometheus_http_requests_total)

 {} 2495 #最近总共请求数为2495次,用于计算返回值的总数 (如http请求次数)

image.png

image.png

count() #统计返回值的条数

count(node_os_version)

{} 2 #一共两条返回的数据,可以用于统计节点数、pod数量等

http://39.101.77.50:9090/graph?g0.expr=count(node_os_version)&g0.tab=1&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h

image.png

image.png

count_values("node_version" ,node_os_version)

#统计不同的系 统版本节点有多少

abs()

#返回指标数据的值 abs(sum(prometheus_http_requests_total{handler="/metrics"}))

absent()

#如果监指标有数据就返回空,如果监控项没有数据就返回1,可用于对监控项设置告警通知(如果返回值等于1就触发告警通知) absent(sum(prometheus_http_requests_total{handler="/metrics"}))

stddev() #标准差

stddev(prometheus_http_requests_total) #5+5=10,1+9=10,1+9这一组的数据差异就大,在系统是数据波动较大,不稳定

stdvar() #求方差

stdvar(prometheus_http_requests_total)

topk() #样本值排名最大的N个数据

topk(6, prometheus_http_requests_total) #取从大到小的前6个

bottomk() #样本值排名最小的N个数据

bottomk(6, prometheus_http_requests_total) #取从小到大的前6个

rate()

#rate函数是专门搭配counter数据类型使用函数,rate会取指定时间范围内所有数据点,算出一组速率,然后取平均值作为结果,适合用于计算数据相对平稳的数据。

rate(prometheus_http_requests_total[5m])

rate(apiserver_request_total{code=~ "^(?:2..)$"}[5m])

rate(node_network_receive_bytes_total[5m])