bigywater.tech
微服务 · 71

Prometheus 抓取模型:pull、间隔与过期

Prometheus 怎么保证抓取间隔?目标挂了、序列消失之后数据多久才“消失”?抓取超时会怎样?比抓取间隔更短命的任务会不会被抓到?这篇用 Prometheus 3.15.0 逐项量出来。

±2 ms
抓取间隔 1 s 和 5 s 时相邻样本间隔相对设定值的最大偏差
1.9 s vs 29.9 s
target 停了之后即时查询查不到所用的时间:普通样本与带显式时间戳的样本(lookback-delta 设成 30 s)
1 / 20 vs 20 / 20
只活 2 s 与活 12 s 的批处理任务被 Prometheus 抓到过的个数(抓取间隔 5 s)

采样时间戳

实测 · 本机执行输出
  抓取间隔 | 样本数 | 相邻样本间隔 最小(ms) | 中位(ms) | 最大(ms) | 标准差(ms)
  -----+-----+---------------+--------+--------+--------
  1 s  | 61  | 998           | 1000   | 1002   | 1.5    
  5 s  | 13  | 4998          | 5000   | 5002   | 1.4    
  Prometheus 按固定的间隔调度抓取(每个 target 有一个由哈希决定的起始偏移,不会所有 target 同时抓取);相邻样本的间隔几乎恰好等于抓取间隔,偏差在几毫秒以内

Prometheus 按固定间隔调度抓取,相邻样本的间隔偏差在毫秒级。

过期与 lookback

实测 · 本机执行输出
  情形                    | 从停止/消失到即时查询查不到 | 那时 up 的值
  ----------------------+----------------+---------
  (a)target 进程停了        | 1.9 s          | 0       
  (b)target 还在,一条序列消失   | 1.9 s          | 1       
  (c)样本带显式时间戳,target 停了 | 29.9 s         | 0       
  (d)对照:不带时间戳,target 停了 | 2.0 s          | 0       
  抓取失败(a)或者序列从成功的抓取结果里消失(b)时,Prometheus 在下一次抓取时写一个 staleness 标记,即时查询马上查不到(不超过一个抓取间隔);带显式时间戳的样本没有 staleness 标记,要等 lookback-delta 过去才查不到

抓取失败或序列消失时下一次抓取写 staleness 标记,即时查询立刻查不到;带显式时间戳的样本要等 lookback-delta。

抓取超时

实测 · 本机执行输出
  target 响应延迟 | up | scrape_duration_seconds | 近 1 分钟 m 的样本数 | 近 1 分钟 up 的样本数
  ------------+----+-------------------------+---------------+---------------
  0.5 s       | 1  | 0.51 s                  | 4             | 4             
  1.5 s       | 1  | 1.50 s                  | 4             | 4             
  3.0 s       | 0  | 2.00 s                  | 0(没有样本)       | 4             
  响应超过 scrape_timeout 的抓取算失败:up 变成 0,这次的数据一条都不收(m 没有样本),但 up 和 scrape_duration_seconds 这些元数据照样记录

响应超过 scrape_timeout 的抓取整次失败,不收任何数据,up = 0。

短命任务

实测 · 本机执行输出
  活 2 s 的 20 个任务里被抓到过的有 1 个;活 12 s 的 20 个任务里被抓到过的有 20 个
  被抓到的活 12 s 的任务:从登记到第一个样本 最小 1.9 s、中位 5.9 s、最大 10.7 s;每个任务被抓到 1~3 次(中位 2 次)
  抓取间隔只是一个因素:新登记的 target 从写入 file_sd 文件到出现第一个样本要等几秒(上面的“登记到第一个样本”那一行;延迟的构成我印象里是服务发现的更新有批量节流加上 target 自己的第一次抓取,没有逐项验证),任务比这个延迟还短就一次都抓不到。这类任务应该主动把指标推给 Pushgateway 之类的中间层,或者在退出前自己上报
ERRORS {}

新登记的 target 要等几秒才有第一个样本,短命任务容易被漏掉,需要推送。

分步演示

抓取模型
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / Go / nginx / Envoy / etcd / Consul / Nacos / OpenTelemetry / Prometheus(按各篇注明用到哪些及版本);所有服务都是本机自己起的进程,端口 9150 以上,只监听 127.0.0.1,不连任何外部服务,不碰本机已有的实例;故障用 kill -9 进程、让连接断开或在代码里注入延迟与错误来制造;计时用 time.perf_counter,数字每次运行会有小幅抖动。Prometheus 3.15.0;被抓取的服务是我写的 Python HTTP 服务;staleness 一节把 --query.lookback-delta 设成 30 s(默认值我印象里是 5 分钟,没有实测默认值);短命任务一节用 file_sd 登记,服务发现的更新节流机制是我印象里的解释,没有验证,表中的数字是实测的;每节只跑了一次,批处理任务的启动时刻是固定种子
    • 没有验证:Pushgateway 的使用与其副作用;remote write 接收端的行为;大量 target 时的调度均匀性;Kubernetes 服务发现的延迟;honor_timestamps、honor_labels 等选项;target 间 scrape 偏移的具体算法
    京ICP备2026067502号-1京公网安备11010502063487号