Prometheus-PromQL

Prometheus收集的指标看起来不够直观,有些信息需要进行一些计算转换才方便用户查看。

  • avg

  • instance

计算某个指标在一定时间范围内的变化速率

  • rage:取指定时间范围内所有数据点,取平均值作为结果。

  • irate计:取指定时间范围内的最近两个数据点计算速率。

irate适合快速变化的计数器 counter,rate适合缓慢变化的计数器 counter 对于快速变化的计数器,如果使用rate,因为使用平均值,会把峰值削平。

范围查询

直接通过PromQL表达式查询时返回值只会包含该时间序列中的最新的一个样本值,这样的返回结果称之为“瞬时向量”。这样的表达式称之为 瞬时向量表达式。

如果我们想要过去一段时间范围内的样本数据时,则需要 区间向量表达式。相比与瞬时向量表达式的区别在于区间向量表达式中我们需要定义时间选择的范围,时间范围通过时间范围选择器[]进行定义。

例如,查最近5分钟内的所有样本数据:

http_request_total{}[5m]

该表达式将会返回查询到的时间序列中最近的5分钟的所有样本数据

PromQL的时间范围选择器支持的时间单位:

  • s 秒

  • m 分钟

  • h 小时

  • d 天

  • w 周

  • y 年

操作符

PromQL支持丰富的操作符,用户可以使用操作符对进一步的对事件序列进行二次加工。这些操作符包括:数学运算符,逻辑运算符,布尔运算符等等。

数学运算

例如,通过指标node_memory_free_bytes_total获取当前主机可用内存大小,其样本单位为Bytes。但这个单位并不适合阅读,如果想转换成MB或GB显示时,只需要将查询到的样本值进行单位换算即可

node_memory_free_bytes_total / (1024 * 1024)	# MB显示
node_memory_free_bytes_total / (1024 * 1024 * 1024)	# GB显示

同时,同类型的多个样本值之间还能进行运算,其结构就跟数学算式一样。PromQL支持的运算符号为:

  • + 加法

  • - 减法

  • * 乘法

  • / 除法

  • % 求余

  • ^ 幂运算(次方)

布尔运算

# 计算内存使用率是否大于总内存的95%
(node_memory_bytes_total - node_memory_free_bytes_total) / node_memory_bytes_total > 0.95

支持的布尔运算符如下:

  • == 相等

  • != 不相等

  • > 大于

  • < 小于

  • >= 大于等于

  • <= 小于等于

使用bool修饰符改变布尔运算符的行为

布尔运算符的默认行为是对时序数据进行过滤。而在其它情况下我们可能需要的是真正的布尔结果。例如,想要知道当前HTTP请求量是否 大于等于1000,如果大于等于1000则返回1(true),否则返回0(false)。

http_requests_total > bool 1000

集合运算符

有时需要在多个瞬时向量之间进行相应的集合操作,目录PromQL支持以下集合运算符:

  • and 并且

  • or 或者

  • unless 除非

操作符优先级

对于复杂类型的表达式,需要了解运算操作的运行优先级。就像数学运算中的括号、乘、除的优先级一样。

在PromQL操作符中优先级由高到低依次为:

  1. ^

  2. *, /, %

  3. +, -

  4. ==, !=, <=, <, >=, >

  5. and, unless

  6. or

聚合操作

PromQL的聚合操作符可以用于将瞬时表达式返回的样本数据进行聚合,形成一个新的序列

支持的聚合操作符如下:

  • sum 求和

  • min 最小值

  • max 最大值

  • avg 平均值

  • stddev 标准差

  • stdvar 标准差异

  • count 计数

  • count_varlues 等于某个值的计数

  • bottomk 后n条时序

  • topk 前n条时序

  • quantile 分布统计

使用聚合操作的语法如下:

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]

其中只有conut_values,quantile,topk,bottomk支持参数(parameter)

  1. without用于从计算结果中移除列举的标签,而保留其它标签。by则正好相反,结果向量中只保留列出的标签,其余标签则移除。

例如:

sum(http_requests_total) without (instance)
# 输出的标签跟下面的一样
sum(http_requests_tail) by (code,handler,job,method)
  1. count_values用于统计时间序列中每一个样本值出现的次数。count_values会为每一个唯一的样本值输出一个时间序列,并且每一个时间序列包含一个额外的标签。 例如:

count_values("count", http_requests_total)

内置函数

除了前面看到的irate函数外,Prometheus还提供了很多其它的内置函数,可以对时序数据进行丰富的处理

计算Counter指标增长率

Counter类型的监控指标其特点是只增不减,在没有发生重置(如服务器重启,应用重启)的情况下其样本值应该是不断增大的。为了能够更直观的表示样本数据的变化剧烈情况,需要计算样本的增长速率。

  • increase:获取区间向量中的第一个后最后一个样本并返回其增长量

  • rate:直接计算区间向量v在时间窗口内平均增长速率。

  • irate:同样用于计算区间向量的计算率,但是其反应出的是瞬时增长率。irate函数是通过区间向量中最后两个样本数据来计算区间向量的增长速率。

预测Gauge指标变化趋势

在一般情况下,为了确保业务的持续可用运行,会针对服务的资源设置相应的告警阈值。例如,当磁盘空间剩余指定值时向管理人员发送告警通知。这种基于阈值的告警模式对当资源用量是平滑增长的情况下是能够有效的工作的。但如果资源不是平滑变化时,比如有些业务增长,存储空间的增长速率提升了几倍,这时如果还是基于原有的阈值去触发告警,则有可能当管理人员收到告警时还未处理。系统就已经不可用了。因此阈值通常来说不是固定的,需要定期进行调整才能保证该告警阈值能够发挥其作用。 Prometheus中则有一个predict_linear(v range-vector,t scalar)函数可以帮助管理人员更好的处理此类情况。predict_linear函数可以预测时间序列vt秒后的值。它基于简单线性回归的方式,对时间窗口内的样本数据进行统计,从而可以对时间序列的变化趋势做出预测。

例如:基于2小时的样本数据,来预测主机可用磁盘空间是否在4小时后被耗尽。

predict_linear(node_filesystem_free{job="node"}[2h], 4 * 3600) < 0

最后更新于