Prometheus Subqueries in VictoriaMetrics
没有PromQL Subqueries时
以前不支持Subqueries时,类似以下这种联合查询是不被允许的:
max_over_time(rate(my_counter_total[5m])[1h])
predict_linear(rate(my_counter_total[5m])[1d], 3600)
以前执行联合查询的方式:把内部子查询先用rule record实现,再引用rule record
instance:my_counter:rate5m = rate(my_counter_total{job="myjob"}[5m])
# You can use this new metric now in rules, alerts or graphs.
instance:my_counter:predict_linear1d_1h_rate5m =
predict_linear(instance:my_counter:rate5m{job="myjob"})[1d], 3600)
PromQL Subqueries
-
过去一小时每秒错误超过 10 次的时间百分比:
avg_over_time((rate(errors_total[5m]) > bool 10)[1h:1m]) -
过去一小时的网络带宽的第 95 个百分位数:
quantile_over_time(0.95, rate(node_network_receive_bytes_total[5m])[1h:1m]) -
最近 30 分钟每秒的最小请求数:
min_over_time(rate(requests_total[5m])[30m:]) -
最后一小时的最大汽车加速度:
max_over_time(deriv(rate(traveled_meters_total[1m])[5m:])[1h:])
Extending Prometheus subqueries(VictoriaMetrics supports Prometheus subqueries and extends them)
VictoriaMetrics 提供以下扩展:
-
可以在查询的任何地方添加Offsets
以下查询返回前一天的缓存请求数:
(rate(hits_total[5m]) + rate(miss_total[5m])) offset 1d这等效于以下 PromQL 查询:
rate(hits_total[5m] offset 1d) + rate(miss_total[5m] offset 1d)这在构建具有不同偏移量的多个图形时特别有用。例如,以下查询返回“今天”、“昨天”和“一周前”的 rps 图,因此 rps 是随时间增加还是减少变得很明:
with (
rps = rate(requests_total[5m]),
)
union(
label_set(rps, “graph”, “today”),
label_set(rps offset 1d, “graph”, “yesterday”),
label_set(rps offset 7d, “graph”, “week_ago”),
) -
外部查询中的 [range:] 可以写成没有尾随冒号的 [range] :
min_over_time(rate(requests_total[5m])[1h])
-
外部和内部查询都可以省略方括号:
deriv(rate(requests_total))
它等效于以下具有从 query_range API 获取的步长值的 PromQL 查询:
deriv(rate(requests_total[step])[step:step])
该步长也称为interval,等于 Grafana 中图形上两个相邻点之间的duration时间
如果 VictoriaMetrics 变得小于两个时间序列点之间的间隔,它会自动调整太小的范围,因此图表在小缩放级别或大刮擦间隔上保持可见(和可用)。
Prometheus subquery pitfalls
虽然子查询很强大,但它们很容易被滥用。例如,以下查询将返回不正确的结果:
rate(sum(requests_total)[5m:])
查询对所有requests_total计数器求和,然后计算总和的速率。问题在于查询处理计数器重置的错误——如果某些requests_total时间序列被重置(例如,由于微服务重启),那么总和可能会下降一点,因此将返回rate不正确的结果。Prometheus 不提供修复此类查询的功能。唯一的方法是sum交换rate:
sum(rate(requests_total[5m]))
VictoriaMetrics 提供了remove_resets函数,可用于修复原始查询:
rate(sum(remove_resets(requests_total))[5m])
remove_resets函数从 中删除计数器重置requests_total,返回始终增加的时间序列,可以安全地求和并传递给rate.