Prometheus 中的 Bucket(桶)是什么?
Bucket 是 Histogram 指标的分桶;经典 Histogram 的每个桶记录"小于等于 le 边界的观测数",暴露为 xxx_bucket{le="0.5"} 序列。本文讲清桶的累积语义、histogram_quantile 计算原理与桶边界设计方法。
Bucket 是直方图(Histogram)的分桶:你定义一组上界(le),经典Histogram由客户端库/exporter维护每个上界的累计计数,Prometheus抓取保存;原生Histogram的编码不同——request_duration_seconds_bucket{le="0.5"} 的值表示耗时 ≤0.5 秒的请求总数。
桶是怎么工作的
定义桶边界 [0.1, 0.5, 1, 5] 后,客户端暴露这样的序列:
request_duration_seconds_bucket{le="0.1"} 105
request_duration_seconds_bucket{le="0.5"} 480 ← 含 ≤0.1 的 105
request_duration_seconds_bucket{le="1"} 760
request_duration_seconds_bucket{le="5"} 799
request_duration_seconds_bucket{le="+Inf"} 800 ← 总是等于总数
桶是累积的——每个桶包含前面所有桶的计数,le="+Inf" 兜底等于观测总数。
为什么这样设计
累积结构让分位数可以插值计算:
histogram_quantile(0.95, sum(rate(request_duration_seconds_bucket[5m])) by (le))
Prometheus 找到 P95 落在哪个桶,在桶内线性插值出近似值。误差取决于桶的疏密——关键区间桶越密,分位越准。
桶边界设计原则
- 围绕 SLO 布点:SLO 是 500ms,就在 300/400/500/600/800ms 附近加密;
- 覆盖全量程:最小有限桶已包括所有更小观测,+Inf兜底包括更大值;有限边界范围决定分位估计分辨率;
- 数量适中:每桶 = 一条序列 × 标签组合数,桶数需按SLO精度、流量和标签基数预算选择,不存在统一10–20个最优值。
常见问题(FAQ)
Q:桶定错了能改吗? 可以改代码里的边界,但历史数据桶结构不变,变更前后分位估计可能变化;滚动迁移时不同实例边界不一致,直接按le聚合可能失真,需协调边界或分版本查询。
Q:bucket 序列能直接画图吗? 一般不直接画,配 rate + histogram_quantile 或 heatmap 面板使用。