如何在PromQL中获取一段时间内95分位数的最大值与平均值
问题:用PromQL获取一段时间内95分位数的最大值和平均值
需求是基于Istio的请求时长直方图,获取一段时间内95分位数的最大值和平均值,但遇到以下问题:
- 直接用
histogram_quantile只能得到当前瞬时的95分位数,无法直接调用max_over_time() - 尝试用
quantile_over_time()直接作用于直方图桶的聚合结果,得到的是每个le桶的异常小值,不符合预期
错误原因分析
quantile_over_time()的作用对象是单个时间序列的数值,而非直方图的桶集合。当你把它用在sum(rate(...)) by (le, destination_workload)的结果上时,它会对每个le桶的rate值单独计算分位数,这和我们需要的“请求时长的95分位数”完全不是一个概念,所以得到的结果没有意义。
解决方案:使用子查询生成范围向量
PromQL支持子查询,可以先在指定步长下计算每个时间点的95分位数,生成范围向量后,再用max_over_time()或avg_over_time()计算统计值。
1. 获取一段时间内95分位数的最大值
比如要统计过去1小时内,每1分钟计算一次95分位数,然后取这些值的最大值:
max_over_time( ( histogram_quantile( 0.95, sum(rate(istio_request_duration_milliseconds_bucket{destination_workload=~"service", reporter="source"}[1m])) by (le, destination_workload) ) )[1h:1m] )
2. 获取一段时间内95分位数的平均值
把上面的max_over_time()替换为avg_over_time()即可:
avg_over_time( ( histogram_quantile( 0.95, sum(rate(istio_request_duration_milliseconds_bucket{destination_workload=~"service", reporter="source"}[1m])) by (le, destination_workload) ) )[1h:1m] )
逻辑说明
- 内层的
histogram_quantile:每1分钟基于最近1分钟的请求数据计算一次95分位数,输出瞬时向量 - 子查询
[1h:1m]:将瞬时向量转换为范围向量,包含过去1小时内每1分钟的95分位数结果 - 外层的
max_over_time()/avg_over_time():对范围向量中的所有95分位数数值,计算最大值或平均值
内容的提问来源于stack exchange,提问作者FigureOfCode
相关产品推荐
相关产品推荐

