You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何理解Prometheus查询函数及Grafana直方图百分位绘图异常

问题解答

关于累积密度分布的疑问

你对累积密度分布的理解是正确的,CDF在x点的取值就是概率密度函数曲线在x左侧的总面积,代表随机变量取值小于等于x的概率。你对PromQL执行逻辑的理解也没问题:rate计算过去1分钟内每个bucket的请求增量速率,累加所有bucket的速率就能得到总请求速率,单个le对应bucket的速率除以总速率,就是延迟小于等于该le值的请求占比,完全符合CDF的定义。

关于按标签组合计算分位的疑问

histogram_quantile函数会将输入指标中的le标签作为特殊的桶边界标识,剩下的所有非le标签都会作为独立的分组维度,每个分组单独计算一次分位值。比如你没有做sum聚合的时候,原始bucket指标带有code标签,那么最终计算出来的分位结果会为每一组handler+method+code的组合返回独立的分位值。你当前的sum语句按handler, method, le聚合,相当于把code标签的数值合并了,所以最终只会按handler+method分组返回分位结果。

测试场景分位值等于桶上界的原因

你观察到的现象既不是查询语句错误,也不是Grafana绘图逻辑有问题,是Prometheus直方图分位计算的固有特性,和你的测试场景、桶配置有关:

  • histogram_quantile默认假设每个桶内的请求延迟是均匀分布的,基于线性插值计算分位值
  • 你测试时只发起固定延迟的请求,所有请求都落在同一个桶里:3秒的请求满足2 < 3 <=4,全部落在le=4.0的桶中,此时le=2.0的桶请求数为0,计算0.99分位时插值结果就会直接取该桶的上界4秒
  • 你设置Thread.sleep(4000)时,实际请求延迟会叠加接口处理、指标打点的额外耗时,最终延迟超过4秒,就会落到le=8.0的桶中,计算出来的分位值自然接近8秒
  • 这种误差在生产环境会大幅降低:生产环境请求延迟是连续分布的,不会全部集中在同一个桶中,插值结果会更接近真实值。如果要降低误差,可以在你关注的延迟区间配置更密的桶,比如在2秒到8秒之间增加3、5、6、7的桶边界,就能显著提升分位计算的精度。

验证方法

你可以直接执行如下PromQL查看各桶的请求速率,就能确认请求实际落在哪个桶中:

sum(rate(http_request_duration_seconds_bucket{method="POST",handler="TestController.testLatencyTime"}[1m])) by (le)

内容的提问来源于stack exchange,提问作者PainIsAMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 04:36:03