LabHub
学习 学习路径 课程

PCA — Prometheus 认证助理

rate 为什么不给整数,le 为什么不能丢

在 LabHub 中继续学习

一句话总结

PromQL 中最常犯的两个错误,是在 sum 之后使用 rate,以及计算分位数时丢掉 le。二者都不会报错,还会返回看似合理的数字,因此可能在仪表板里存活数月。

概念图: 在 sum 之后使用 rate · 计算分位数时丢掉 le · 外推(extrapolation) · rate 的三个陷阱

为什么需要它

计数器直接绘制只会得到一条向右上方延伸的直线,没有任何信息,因此要用 rate 查看每秒增长率。但 rate 并不是简单除法,而会进行外推(extrapolation)。它先计算范围内第一个和最后一个样本的差,再按样本与范围边界之间的距离成比例扩展。因此 increase 会返回 3.4 这样的值,即使错误实际上恰好发生了 3 次。这不是错误,而是定义如此;需要“准确 N 次”的计算不应使用它。

工作原理

rate 的三个陷阱

第一,窗口相对于抓取间隔不能太窄。rate 至少需要窗口内有两个样本才能给出结果。如果抓取间隔为 15 秒、窗口为 20 秒,有些时刻窗口中只有一个样本,结果就会为空;图表上表现为缺口,告警中则表现为“条件不成立”。经验法则是窗口 ≥ 抓取间隔 × 4,告警使用至少 5 分钟。

第二,顺序。

# 틀림 — 카운터를 먼저 더하면 파드 재시작(리셋)이 감지되지 않는다
rate(sum(http_requests_total) by (route)[5m:])

# 맞음 — rate 를 먼저, 집계는 그다음
sum(rate(http_requests_total[5m])) by (route)

计数器重置校正只有在单条时间序列上才准确。如果一个 Pod 重启后降为 0,合计后看起来只像“总量稍有下降”,无法识别为重置。结果是请求率低于实际值,而且每次部署看起来都像流量减少。

第三,irate 只查看最后两个样本。它适合在仪表板中观察瞬时反应,但绝不能用于告警,一次噪声就会触发。

lookback delta 与 staleness

即时向量选择器会从求值时刻 T 向过去最多查找 5 分钟(默认 lookback delta),并使用最近的样本。这就是为什么 T 时刻不必恰好存在样本。但如果期间出现 stale marker,该时间序列会从结果中移除。

histogram_quantile 的线性插值

le="1"     누적 9812
le="2.5"   누적 9993
목표 = 0.99 × 10000 = 9900

추정 = 1.0 + (9900 - 9812) / (9993 - 9812) × (2.5 - 1.0) = 1.729초

结果会得到看似精确的 1.729 秒,但没人知道这个桶里的 181 个请求实际分布在哪里。它们可能全部为 1.05 秒,也可能全部为 2.4 秒。由此得出三条实务规则:设置与 SLO 阈值完全相同的桶边界;在关注区间设置更密集的边界;让最上方的有限桶大于实际超时时间。如果 p99 超出最后一个有限边界,函数会固定返回该边界值,无法看出情况究竟有多糟。

聚合时必须保留 le

# 틀림 — le 를 버리면 버킷이 뭉개져 의미 없는 숫자가 나온다
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (route))

# 맞음
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, route))

同理,avg(histogram_quantile(...)) 也是错误的。不要对分位数取平均,而应先合并桶计数,再在其上计算分位数。

考试偏爱的其他要点

元素 核心
offset / @ 指定相对偏移/绝对 epoch 时刻
bool 将比较结果变成 0、1,而不是用于过滤
on / ignoring 指定二元运算的匹配标签
group_left / group_right 允许多对一、一对多匹配
unless 从左侧移除与右侧匹配的时间序列
子查询 expr[30m:1m]——范围:分辨率
predict_linear 对仪表做线性回归外推,用于容量告警
absent 时间序列不存在时返回 1

现场会遇到的情况

家庭实验室仪表板中存活最久的错误,是遗漏 by (le。它会返回值,图表也能画出来,甚至走势看起来很合理。发现它只有一种办法:搜索所有包含 histogram_quantile 的查询,逐一目视确认聚合子句中是否包含 le。大多数团队都会漏掉至少一个。

基数事故通常在部署后立刻呈阶梯状出现。绘制 prometheus_tsdb_head_series,再与部署时间重叠,就能立即找到原因提交。至于哪个指标是罪魁祸首,一条 topk(10, count by (__name__)({__name__=~".+"})) 就能找出。

下一实验要做什么

/root/pca-promql/ 下把八条查询分别写入文件:按路由统计的请求率与错误率、正确保留 le 的 p99、基数诊断、使用 predict_linear 的磁盘预测、在低流量下防止幽灵告警的 AND 门、结合 upabsent 的抓取健康检查,以及最后把两个窗口以 AND 连接的燃烧率表达式。评分采用字符串匹配,因此请准确使用题目指定的指标名称和窗口。