Prometheus分位值Sumary和Histogram数据详解
1 分位值基础概念
1.1 什么是分位值
分位值(也叫分位数、Quantile)是描述随机变量分布的特征统计量。将随机变量分布曲线与X轴围成的总面积做N等分,对应的N-1个分界点数值即为N分位值。
在数据分析与监控场景中,最常用的是四分位体系与高阶分位:
-
25分位值(P25,下四分位):有25%的样本小于等于该值
-
50分位值(P50,中位数):有50%的样本小于等于该值
-
75分位值(P75,上四分位):有75%的样本小于等于该值
-
P90、P95、P99等高阶分位:常用于刻画系统长尾表现,对应90%、95%、99%的样本上限
1.2 分位值的业务意义
分位值的核心逻辑是:将所有样本从小到大排序,取排名处于N%位置的数值作为该分位结果。相比平均值,分位值能更真实地反映主体样本的实际水平,核心价值在于:
-
平均值易被极端值“削峰填谷”,无法区分多数正常样本与少量异常长尾;高分位可以过滤极端异常,体现系统稳态下的性能表现
-
可量化尾部风险:例如 P99 延迟代表 99% 的请求都能在该时间内完成,仅 1% 的请求超过该阈值,是服务 SLO(服务等级目标)的核心指标
-
注意:高分位不适用于所有场景。在金融支付、强一致性交易等对可靠性要求 100% 的场景,不能忽略长尾异常,需关注全量数据与最大值
2 分位值的计算方法
2.1 基础计算逻辑
以N个有序样本为例,φ分位(0≤φ≤1)对应排名为φ×N的样本位置。当排名不是整数时,通用做法是通过线性插值计算最终结果,而非直接取邻近整数位置的原始值。Prometheus中histogram_quantile函数也采用桶内线性插值的估算逻辑。
2.2 手工计算示例
以数据集 [65, 23, 55, 78, 98, 54, 88, 90, 33, 48, 91, 84] 为例,计算四分位值:
-
数据排序
从小到大排列为:23, 33, 48, 54, 55, 65, 78, 84, 88, 90, 91, 98,共12个样本,11个间隔。 -
四分位间隔
每段四分位对应间隔数:11 ÷ 4 = 2.75 -
分位值插值计算
-
25分位(P25)
位置:第1 + 2.75 = 3.75个样本处,即第3个值(48)与第4个值(54)之间的0.75位置
计算:48 + 0.75 × (54 - 48) = 52.5 -
50分位(P50 / 中位数)
位置:第1 + 2.75 × 2 = 6.5个样本处,即第6个值(65)与第7个值(78)之间的0.5位置
计算:65 + 0.5 × (78 - 65) = 71.5
也可通过偶数样本中位数公式直接计算:(65 + 78) ÷ 2 = 71.5 -
75分位(P75)
位置:第1 + 2.75 × 3 = 9.25个样本处,即第9个值(88)与第10个值(90)之间的0.25位置
计算:88 + 0.25 × (90 - 88) = 88.5
2.3 练习
将1到100的整数序列做10等分,使用上述线性插值方法,计算P10(10分位)与P90(90分位)的数值。
总间隔 99,10 等分步长 9.9;P10 位置 10.9,结果 10.9;P90 位置 90.1,结果 90.1。
3 Histogram(直方图)数据类型
Histogram是Prometheus中用于统计数值分布的核心指标类型,本质是客户端分桶计数、服务端计算分位的累计直方图方案。

3.1 指标组成与格式
一个基础Histogram指标包含三类时间序列:
-
_bucket分桶计数序列
每个bucket是一个累计计数器,标签le代表“小于等于该上边界”(less or equal, upper inclusive bound),即统计所有观测值 ≤ 该边界的样本总数。
示例(TSDB压缩块大小):代表描述"tsdb_compaction_chunk_size_bytes"小于这个le的记录数位多少个: prometheus_tsdb_compaction_chunk_size_bytes_bucket{le="32"} 0 tsdb压缩块大小小于32bytes的有0个。 prometheus_tsdb_compaction_chunk_size_bytes_bucket{le="48"} 806 tsdb压缩块大小小于48byte的有806个。 prometheus_tsdb_compaction_chunk_size_bytes_bucket{le="72"} 1683 tsdb压缩块大小小于72byte的有1683个。 prometheus_tsdb_compaction_chunk_size_bytes_bucket{le="108"} 2842 tsdb压缩块大小小于108byte的有2842个。 ... prometheus_tsdb_compaction_chunk_size_bytes_bucket{le="+Inf"} 6091 最后一定是一个"+Inf"(表示"正无穷")的记录,因为算分位值的时候要用到"+Inf"。 值得注意的是,一个新的数据上报时,会把大于这个value的bucket全部"+1"。 Prometheus可以使用histogram数据类型可以采用分位值的方式随机采样短时间范围内的数据,从而及时发现问题,这需要配合histogram_quantile函数来使用。 举个例子: HTTP请求的延迟柱状图(下面的"0.95"表示的是分位值,你可以根据需求自行修改即可。) histogram_quantile(0.95,sum(rate(prometheus_http_request_duration_seconds_bucket[1m])) by (le)) histogram_quantile(0.95,sum(rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m])) by (le))核心特性:每上报一个新样本,所有
le值 ≥ 该样本值的bucket计数都会+1;+Inf(正无穷)桶为必选项,其值等价于总样本数。 -
_sum样本总和序列所有观测样本的数值总和。 代表记录的和,比如这个指标就是"tsdb_compaction_chunk_size_bytes"tsdb压缩块大小字节总和为"1.086535e+06"(将近1MB)。 -
_count样本总数序列观测样本的总数量。 代表记录"tsdb_compaction_chunk_size_bytes"的数量和,就是一共"6091"次上报。
3.2 分位计算原理
Histogram本身不存储分位结果,需通过PromQL函数histogram_quantile(φ, buckets)基于分桶数据估算分位值:
-
先找到累计计数覆盖φ比例的目标桶;
-
假设样本在桶内呈均匀线性分布,通过线性插值计算分位对应数值;
-
结果为近似估算值,精度取决于bucket边界的疏密程度,桶越密集精度越高。
注意:bucket是累计计数器,计算时间窗口内的分位必须先通过
rate()或increase()获取窗口内的增量,否则结果无统计意义。
3.3 PromQL使用示例
# 1分钟窗口全量HTTP请求的P95延迟
histogram_quantile(0.95, sum(rate(prometheus_http_request_duration_seconds_bucket[1m])) by (le))
# 5分钟窗口指定接口的P95延迟
histogram_quantile(0.95, sum(rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m])) by (le))
4 Summary(摘要)数据类型
Summary同样用于统计数值分布,核心特点是客户端预计算分位、服务端直接读取结果,分位计算在应用侧流式完成。
4.1 指标组成与格式
一个Summary指标包含三类时间序列:

summary数据指标格式说明:
- XXX{...,quantile=XXX}:
使用quantile关键字定义具体的分位值。
prometheus_target_interval_length_seconds{interval="15s",quantile="0.01"} 14.997928423
代表就是"1"分位值为"14.997928423"秒。
prometheus_target_interval_length_seconds{interval="15s",quantile="0.05"} 14.998842243
代表就是"5"分位值为"14.997928423"秒。
prometheus_target_interval_length_seconds{interval="15s",quantile="0.5"} 15.000025528
代表就是"50"分位值为"15.000025528"秒。
prometheus_target_interval_length_seconds{interval="15s",quantile="0.9"} 15.000811084
代表就是"90"分位值为"15.000811084"秒。
prometheus_target_interval_length_seconds{interval="15s",quantile="0.99"} 15.001590525
代表就是"99"分位值为"15.001590525"秒。
- XXX_sum:
代表记录的和,比如这个指标就是"target_interval(采集目标间隔时间)"消耗描述的和为"4785.00520029"。
- XXX_count:
代表记录的数量和,一共上报了"319"次。
4.2 核心特性
-
分位点必须在客户端埋点时预先定义,运行期无法新增未配置的分位;
-
客户端通常采用流式算法(如GK算法)基于滑动窗口计算,单实例分位精度相对更高;
-
不支持跨实例聚合:分位值不满足可加性,对多个实例的quantile结果做sum、avg等运算无统计意义,属于典型错误用法。
5 Histogram与Summary全面对比
| 对比维度 | Histogram | Summary |
|---|---|---|
| 分位计算位置 | 服务端PromQL实时计算,依赖histogram_quantile |
客户端SDK流式预计算,服务端直接读取 |
| 分位灵活性 | 支持0~1之间任意分位,查询时自由指定 | 仅支持埋点预设的分位点,运行期不可修改 |
| 多实例聚合 | 支持:先聚合bucket计数,再计算分位,结果有效 | 不支持:分位值无可加性,跨实例聚合结果错误 |
| 结果精度 | 桶内线性插值估算,精度由bucket边界密度决定 | 客户端流式算法输出,单实例精度相对更高 |
| 客户端开销 | 低,仅做分桶累加,逻辑简单 | 高,需维护流式分位算法与滑动窗口状态 |
| 服务端开销 | 高,分位计算为实时运算,高频查询建议配合记录规则优化 | 低,直接读取时序数值,无额外计算开销 |
| 时序数量 | 由bucket数量决定,分桶越多时序越多 | 由预定义分位点数量决定,时序数量可控 |
| 前置配置 | 需提前规划bucket边界 | 需提前定义分位点与滑动窗口大小 |
6 选型建议与常见误区
6.1 选型建议
-
优先选择 Histogram:多副本部署的服务、接口延迟统计、需要跨实例聚合、后续可能调整分位指标的场景,均推荐使用 Histogram,这也是 Prometheus 官方的主流推荐方案。
-
按需选择 Summary:单实例指标、无法提前预估数据范围、不需要跨实例聚合、追求单实例分位精度的场景(如 Go 运行时 GC 耗时等内置指标)可使用 Summary。
-
Bucket 设置原则:优先使用指数分布的桶边界(官方默认延迟桶为指数分布),在数据集中的区域加密桶边界,长尾区域放宽桶宽度,平衡精度与时序数量。
6.2 常见使用误区
-
Histogram 不套 rate() 直接计算分位
bucket 是 Counter 类型,数值单调累计,直接计算得到的是服务启动至今的全量分布,而非指定时间窗口的分布,必须先通过rate()/increase()获取窗口增量。 -
对 Summary 的 quantile 做聚合
分位数不满足可加性,avg()、sum()等聚合操作得到的结果不具备统计含义,属于典型错误用法。 -
混淆估算值与精确值
Histogram 输出的分位是插值估算结果,并非原始样本的精确分位数;对精度要求极高的场景需合理加密 bucket。 -
Bucket 设置不合理
桶过宽会导致分位误差极大,桶过密会导致时序数量爆炸,存储与查询成本飙升,需结合业务数据分布调试。

浙公网安备 33010602011771号