原文计数器样本先增长、急降重置,再次增长。第一个样本位于五分钟左开范围之外。箭头从所选观测指向原文样例的每秒 5/6 速率估计。

Prometheus rate 估计计数器每秒的增长速度

请求计数器回答进程累计记录了多少事件,速率则回答这些事件到来得有多快。Prometheus 的 rate 估计指定范围内每秒平均增长量,修正能够观测到的计数器重置,并向范围边界进行外推。结果具有明确的时间单位,适合观察负载变化;但它不是两次抓取之间全部事件的精确还原,更不能凭空补回没有采到的重启历史。 数值来自原文合成样本的 promtool 实验,其历史本地执行证据与本轮绘图分别保留。五分钟范围排除第零分钟,修正可见重置并外推。每条计数器应先求速率再求和。本轮未运行查询引擎或真实 Prometheus 服务。 采样决定能够推断多少事实 普通计数器在重置前持续增长,进程重启是常见的重置原因。相邻已观测样本出现下降时,计数器函数会按重置处理。不过,如果两次抓取之间已经重启并重新累计,而且新值超过旧样本,重置可能完全不可见。提高抓取频率可以提升观测分辨率,但任何查询都不能确定地恢复一段没有被记录的历史。 应先对每条计数器序列求 rate,然后聚合结果。如果先求和,一台实例的增长可能掩盖另一台实例的重置。标签决定序列身份,替换实例使用新标签时,是开始另一条序列,不是自动接续旧实例。队列长度等仪表值本来就允许正常下降,把它们交给计数器速率函数,会把真实下降错误解释为重置。 选择的范围也是指标含义的一部分 范围选择器左开右闭。在第五分钟求 [5m] 时,恰好位于第零分钟的样本不在范围内。对普通浮点计数器求速率至少需要两个可用样本;只有一个样本时得到空结果,并不表示业务流量为零。因此,范围不仅要覆盖正常抓取周期,还需要考虑偶发漏抓后的样本数量,不能仅凭希望曲线更灵敏就无限缩短。 较长窗口通常会平滑短促突发,也让突发离开平均值的时间更晚;较短窗口响应更快,但观测更少,而且可能变成空结果。应依据事件持续时间与检测目标选择范围,并在面板上明确标注。irate 使用最后两个样本,rate 使用所选范围,两者可以针对同一指标回答不同问题,只要面板清楚说明各自含义,不把数值当成同一种口径比较。告警通常应优先使用 rate:即使整体负载仍然偏高,irate 的短暂下降也可能重置待触发告警的 for 等待。 规则评估周期决定何时提出查询问题,不决定目标已经被抓取了多少次。如果目标每分钟才采集一次,即使面板每秒刷新,也不会凭空产生新的观测。分析告警响应速度时,需要分别检查采集与评估这两个周期,不能只缩短页面刷新时间。 坏掉的样子 刚创建的序列可能要等第二个样本到来后才出现在速率面板。把所有空值都补成零,可能掩盖采集故障。遇到空白,应先检查原始序列、时间戳和抓取状态,再判断业务是否空闲。另一种问题是窗口太长:短时间过载已经影响用户,但平均线被长窗口稀释,看起来始终平稳,告警因而没有达到阈值。 重置修正不代表缺口对准确性没有影响。漏抓可能隐藏突发或多次重启,范围边界的外推本身也属于估计。increase 以事件数量单位表达相应的范围估计,即使原始计数器只有整数,也可能返回小数。如果场景需要精确账务或计费总数,应依靠业务记账记录,不能把监控面板描述成可以完整重建交易流水的工具。 快速验证 保存为 rate.py,运行 python3 rate.py。环境需要已经安装的 promtool,可以从 PATH 找到,或用 PROMTOOL 指定其可执行文件路径。此前记录的执行使用 Python 3.12.14 与 promtool 3.14.0;本轮文章复核没有重新运行该引擎。真实查询引擎在临时目录中评估合成样本,不启动服务器、监听端口或容器,也不联系外部服务。 ...

十二月 24, 2027 · 2 分钟 · XB Field Notes
调试样本在红色 drop 截止标记处终止;请求样本经过 labeldrop 后删除构建标签并保留数值 42;独立的 up 路径保持不变。

样本重新标记在入库前过滤指标

Prometheus 存在多个重新标记阶段,相似语法容易遮住不同作用。目标重新标记在采集之前处理发现目标,样本重新标记则在抓取之后、入库之前处理采集样本。前一个阶段的 drop 可以让某个端点不被抓取,后一个阶段的相同动作则从已经获取的响应中丢弃匹配样本。首先确定阶段,才能判断配置到底改变了哪一部分观测。 样本重新标记在抓取之后、入库之前处理样本。原文样例区分 drop、labeldrop 与自动生成的 up,且剩余请求身份已经唯一。本图没有重跑集成,也不证明生产迁移不会发生冲突。 先决定删除数据,还是删除标签 在 metric_relabel_configs 中,action: drop 匹配组合后的源标签值,并丢弃匹配样本。使用 __name__ 作为输入时,可以拒绝指定指标族。它不是删除这个源标签却保留样本的意思。如果对一个广泛存在的值使用过宽条件,可能丢掉远超预期的数据,所以不能仅凭动作名称中有“删除”就认为它只影响元数据。 action: labeldrop 则把正则表达式用于标签名称,从保留样本中移除匹配标签;labelkeep 只保留名称匹配的标签。两者都不会求和或生成汇总。前一类操作删除观测,后一类操作改变身份,应该按照预期数据契约选择,而不是把名称相近的动作当成可互换参数。留下数值但删掉维度,也可能比直接过滤一部分样本带来更隐蔽的问题。 重新标记表达式默认在两端锚定。替换或过滤规则需要在对应阶段使用正确的源标签与模式。发现元数据通常属于目标阶段,到样本处理阶段时,已不能继续期待使用 __meta_ 输入。需要保留的上下文应提前复制到普通目标标签,而不是假定每个导出指标都会携带内部发现字段。配置语法相同,不代表输入集合也相同。 删除维度之后仍须保持唯一身份 时间序列由指标名和完整标签集合识别。移除区分两条观测的标签,可能让它们身份重叠,产生重复样本冲突或丢失区别。Prometheus 不会自动推断这些数值该求和、取平均还是任选其一。如果真正需要服务总量,应优先采用受控维度的仪表化以及明确查询聚合,而不是把标签删除当成自动汇总机制。 ...

八月 4, 2027 · 2 分钟 · XB Field Notes
八块有界标签与四百个请求标识标签组成的密集网格对照;相同的九组件、二十副本系数得到 1440 与 72000 条序列。

基数是指标的预算

一个很短的指标名,背后可能对应大量存储与查询成本。Prometheus 使用指标名及完整标签集合标识一条时间序列,每出现一种新的实际标签组合,就形成另一条需要采集、建立索引、保留和查询的序列。基数预算关注的是,哪些区别值得付出这笔成本,以及服务增长时,这些区别的数量是否仍有明确上限。它不是单纯要求标签越少越好,而是要求每个维度都有可解释的用途。 原文练习是序列数量模型:八种有界组合全部出现,每个副本都有这些组合。九个经典直方图核心组件和二十副本同等放大两种方案。数量不是实测的内存或磁盘占用。 统计真正出现的组合 标签维度会扩大可能的组合数,但只有每种组合都实际出现时,各维度取值数的乘积才等于真实数量。两条路由、两种方法、两类状态最多可以形成八种组合;如果每条路由只允许一种方法,导出的组合就可能更少。因此既要计算理论上界,也要核对实际输出,并把实例等采集目标标签纳入服务端最终接收的序列估计。 取值集合比标签名字是否好听更重要。标准化路由可以把同一类订单操作归在一起,而包含每个订单编号的原始路径会持续增加取值。请求编号、时间戳、用户标识以及任意查询字符串,都可能随着事件量增长。开发者把标签叫作路由,并不意味着它真的有界;还要检查真实流量中的值,尤其是错误路径、未匹配路径和很少出现的边界请求,避免正常测试掩盖高基数来源。 把指标表示方式一起算进去 对于每组实际标签,普通计数器通常产生一条主要序列,另外可能存在伴随指标。经典直方图则会展开成多个桶、总和与计数组件。如果有六条有限桶边界,再加正无穷桶、总和及计数,每组标签就对应九条核心序列。有些客户端还会导出创建时间序列,真实清单必须把它算上,不能将用于理解原理的简化公式当成完整埋点总量。 多个副本还会增加实例维度。采集间隔决定每条序列多久写入一个样本,保留期限决定历史数据保存多久,它们与不同序列的数量不是同一概念。不断变化的标识还会制造时序更替:生产端已经消失的短命组合,历史样本仍可能继续留在存储里。因此应分别观察活跃序列、新建速度、写入量、内存和查询表现,不能拿一个固定的“每条序列占多少字节”覆盖所有配置与工作负载。 坏掉的样子 看似方便排障的标签,可能把聚合指标变成逐请求事件仓库。只在仪表盘查询中去掉该标签,无法撤销已经发生的采集和保留成本。对每个标识计算哈希,也不会消除其唯一性;截断随机标识通常只是推迟增长问题,同时引入碰撞。如果业务真正需要的是分类统计,就应选择有明确上限的类别,而不是给无限集合换一种编码方式。 也不能为了降低成本,把识别用户影响所必需的区别全部压平。保留有意义且有界的结果或服务维度,把单次请求调查交给具有相应访问控制的日志和链路记录。如果在采集过程中删除标签,还要检查一次采集内是否出现重复的最终序列,以及诊断信息是否丢失。能够修改生产端时,应优先在那里修正,再验证新标签集合,并明确旧历史序列如何随保留策略逐步退出。 快速验证 保存为 cardinality.py 并使用 Python 3 执行。人为构造的事件把路由、方法和状态的每一种组合重复五十次。一种表示只保留这些有界维度,另一种再增加唯一的请求标识。计算假定二十个副本都导出相同的组合,并使用六条有限边界的经典直方图;这个前提在代码旁明确列出,便于读者核对乘法来源。 from itertools import product routes = ["/orders/{order_id}", "/products/{product_id}"] methods = ["GET", "POST"] statuses = ["200", "500"] events = list(product(routes, methods, statuses, range(50))) bounded = {(route, method, status) for route, method, status, _ in events} with_request_id = {(route, method, status, f"request-{i}") for i, (route, method, status, _) in enumerate(events)} finite_buckets = 6 # Core classic-histogram series: finite buckets, +Inf, _sum, _count. # Optional _created series are deliberately excluded from this calculation. series_per_combination = finite_buckets + 3 replicas = 20 bounded_series = len(bounded) * series_per_combination * replicas request_id_series = len(with_request_id) * series_per_combination * replicas assert len(events) == 400 and len(bounded) == 8 assert len(with_request_id) == 400 assert bounded_series == 1440 and request_id_series == 72000 print(f"observed label sets: bounded={len(bounded)}, request_id={len(with_request_id)}") print(f"core classic-histogram series: bounded={bounded_series}, request_id={request_id_series}") print(f"multiplier={request_id_series // bounded_series}x") 四百条事件在有界表示下被聚合为八种组合,带请求标识时则保留四百种。扩展到二十个副本后,两者分别产生一千四百四十条与七万二千条核心直方图序列,相差五十倍。示例明确排除了可选创建时间序列和其他指标族,因此输出是给定假设下的序列数量模型,不是对 Prometheus 内存或磁盘占用进行过真实压测的结果。 ...

七月 21, 2027 · 1 分钟 · XB Field Notes
短批任务把指标推送给 Pushgateway,Prometheus 则独立发起抓取。任务结束后数据托盘仍保留,需要主动清理,不会自动过期。

Pushgateway 保留批任务指标,直到生命周期被主动处理

短生命周期任务可能在 Prometheus 下一次抓取之前就结束。Pushgateway 提供中间层,保留任务推送的指标以供后续抓取,但它不是每个短进程的默认方案。Prometheus 主要建议把它用于适当的服务级批任务结果。保留数据的生命周期与任务自身独立,因此抓取成功不能证明任务最近运行过,也不能证明业务工作已经成功完成。 Pushgateway 指标生命周期独立于任务。稳定分组键控制额外分组,却不建立并发运行顺序;负责人仍须处理替换、新鲜度和精确分组删除。原文未改动的 HTTP 实验仍受阻,本轮绘图未执行。 为稳定的批任务结果建立身份 夜间对账这样的服务级任务,可以把最近结果发布到稳定分组键下。如果把新的运行编号、时间戳或机器身份放进键中,每次运行都可能创建额外分组,而不是更新同一份结果。Pushgateway 没有自动清理旧分组的过期时间机制,负责人需要明确替换或删除相关数据,不能假定退出任务后数据也会跟着消失。 与具体机器相关的批任务,往往可以使用节点导出器的文本文件采集器。共享网关本身也增加了可用性依赖。它的 up 表示 Prometheus 能否抓取网关,不表示每个原始推送任务都健康。应根据观测事件与清理责任选择采集方式,而不是把推送当成绕过服务发现或网络策略的通用办法。任务语义没有确定时,先增加网关并不会自动解决监控定义。 替换范围由 HTTP 方法决定 URL 路径定义分组键,包括任务名称与其他标签对。HTTP PUT 替换这个精确分组中的指标;POST 则替换本次请求包含的同名指标族,同时保留组内其他指标族。POST 不表示给原值递增,也不是向持久事件日志追加一条记录。如果一次报告把数值从七写成九,结果是九,而不是自动累加成十六。 DELETE 删除 URL 标识的精确分组。仅删除任务名构成的分组键,不会删除所有同时包含该任务名和额外标签的分组。网关文档规定的方法顺序允许后续成功推送排在先前已入队的删除之后,这可以用于验证清理结果。不能只看到删除请求被接受,就认定所有名称相似的序列都已经被处理,尤其不能把分组键误当成标签子集查询。 抓取时间不等于最近成功时间 网关通过 push_time_seconds 导出某组最近成功推送的时间。读取指标端点不会推进这个值。Prometheus 为采集样本赋予抓取时间戳,所以刚刚抓到的样本仍可能描述很久以前的任务结果。如果真正关心任务何时成功完成,应把最近成功时间作为独立的仪表值导出,并按任务计划检查其新鲜度。Prometheus 抓取网关时,应设置 honor_labels: true,保留推送数据中的 job 与 instance;否则发生冲突的值会被改名为 exported_job 与 exported_instance。下方实验并未验证这项抓取配置。 ...

五月 13, 2027 · 3 分钟 · XB Field Notes
两个实例的累计桶阶梯先合并为总体阶梯,再估计 p99。合并时保留匹配的 le 桶身份。

Prometheus 直方图保留分桶后的分布信息

延迟平均值可能隐藏一部分特别慢的请求。直方图通过记录落入不同桶的观测数量,保留更多分布信息,但仍然丢弃桶内部的细节。Prometheus 可以从这些计数估计分位数,无需保存每次请求的原始耗时。估计结果取决于桶边界与聚合方式,不能称为完整恢复了原始延迟分布,也不能因为输出包含小数就认为测量具有同样精度。 经典直方图先对每条计数器求速率,再合并兼容桶、保留 le,最后估计分位数。原文合成样例的总体 p99 为 4.94 秒,两秒阈值占比为 50%,平均值为 2.085 秒。正无穷桶返回值不是测得的最大值,也不是阈值保证。本轮绘图没有运行 promtool 或服务器。 经典直方图由多条相关序列组成 经典直方图导出累计的 _bucket 计数器,以及 _count 与 _sum。le 标签表示每个桶包含的上界。一点五秒的观测会增加两秒桶和所有更大的桶,所以这些桶不是互不重叠的区间,不能直接相加得到总请求数。正无穷桶包含全部观测,与总计数对应。一个经典直方图因此不是一条可以单独理解的普通序列。 对于非负延迟观测,分别对总和与总计数应用 rate,可以得到每秒累计的耗时和每秒观测数量;两者相除就是以秒为单位的平均延迟。桶速率则描述选定时间范围内的分布。应该先对各条计数器求速率,再合并实例,这样各序列已经观测到的重置能够独立处理,不会在求和时被另一实例的增长掩盖。 先合并桶,再估计总体分位数 需要整个服务的一个分位数时,应在保留 le 的前提下合并桶速率,再调用 histogram_quantile。查询需要区分服务等维度时,也应保留相应标签。参与合并的桶边界要兼容,事件定义也要一致。如果先把 le 消掉,就丢失了经典分位数函数所需的桶身份,留下的数值无法继续表达累计分布。 ...

一月 6, 2027 · 2 分钟 · XB Field Notes
同一个二百五十毫秒输入分为两条路径。除以一千得到零点二五零秒;只改后缀仍保留数值二百五十,错误地将其解释为秒。上方换算路径与下方仅改名路径明确分开。

把单位写进指标名里

名为 request_duration 的指标会让读者猜测,二百五十究竟表示秒、毫秒还是别的量。面向 Prometheus 的名称,例如 http_request_duration_seconds,能够把单位约定带入查询、记录规则与告警配置。但这个约定必须由正确实现支撑:给毫秒数据的名字加上秒后缀,不会自动改变数值大小,反而可能让监控产生一千倍的误差。名称提供线索,转换逻辑才决定数据是否可信。 图解依据原文的三条十进制定点输入与阈值。历史 promtool 解析及命名检查结果保持不变。名称正确不证明真实埋点正确,应沿采集、导出、查询与显示核对已知输入。 在明确的边界完成换算 每个指标族应只表示一种量和一种单位。Prometheus 建议使用秒、字节等基础单位,并在适用时把单位写为后缀。持续时间与绝对时间戳都可以用秒表示,却不是同一种量,因此不能因为名字都含秒,就把上次成功的时间戳与一次请求的耗时直接相加。帮助文本应写明测量对象、开始结束边界以及含义,让简短名称背后仍有明确的契约。 如果底层库输出毫秒,应在观测或导出边界转换一次,并保留足够精度,避免把很短的耗时截断为零。仪表盘可以按基础单位配置显示,让零点二五秒自动显示为二百五十毫秒,这只改变呈现方式,不改变存储样本。不能仅因为坐标轴显示毫秒,就在记录规则中再做一次换算,否则查询和图表会在不同环节重复缩放。 单位与类型回答不同问题 累计传输字节数通常使用字节加总量后缀,当前内存占用仪表则只使用字节后缀。两者单位相同,但只有前者表示不断累积的工作量,适合计算计数器速率。请求次数按惯例使用总量后缀,无须编造一个物理单位。直方图的桶、总和与计数,还会在耗时指标族名称后加入各自的组件后缀,因此阅读名称时也要识别指标族与导出组件之间的关系。 比例通常表示零到一之间的分数,而百分数使用另一种数值尺度,面板应明确自己期待哪种输入。计数器可以在进程重启时归零,Prometheus 的计数器速率函数会根据观测序列中的下降处理重置,并不要求额外存在创建时间序列。应先分别计算独立计数器的速率,再执行聚合,让各自的重置仍能被识别;不要先把多个实例的累计值混成一条看似连续的曲线。 坏掉的样子 名字正确的指标仍然可能承载错误数值。如果同一个标识下混入秒和毫秒,历史数据已经被污染,修改帮助文字或补一个说明标签不能修复旧样本。单位迁移应被视为契约变化,生产端、查询、告警和仪表盘需要一起核对,历史区间的比较也必须说明边界。旧序列含义不兼容时,可以采用新的指标标识,避免新旧数值被误当成同一种量连续使用。 名称后缀也不会强制执行计数器语义。一个普通运行过程中可以升降的仪表,即使名字带总量后缀,也不适合按累计计数器解释。反过来,已经得到每秒速率后再除以时间窗口,会制造另一种量。这些是维度和测量语义的问题,不能只靠显示格式解决。其他遥测体系可能把单位放在元数据中,应遵循已定义的导出映射,而不是机械重命名所有上游仪器。 快速验证 把代码保存为 units.py,使用 Python 3 执行。程序转换三条人为构造的延迟观测,并输出带帮助文字和类型声明的 Prometheus 文本格式。Decimal 十进制运算使毫秒到秒的换算清楚可见;阈值比较则展示,仅仅改名、却不转换数据的生产端,为什么不能和正确的生产端共用同一条延迟规则。 from decimal import Decimal latency_ms = [Decimal('120'), Decimal('250'), Decimal('630')] latency_seconds = [value / Decimal('1000') for value in latency_ms] threshold_seconds = Decimal('0.300') correct_good = sum(value <= threshold_seconds for value in latency_seconds) rename_only_good = sum(value <= threshold_seconds for value in latency_ms) transferred_bytes = 1024 * 1024 used_ratio = Decimal('25') / Decimal('100') assert correct_good == 2 and rename_only_good == 0 assert sum(latency_seconds) == Decimal('1.000') assert used_ratio == Decimal('0.25') print(f"# within 0.300s: converted={correct_good}/3, rename_only={rename_only_good}/3") print('# HELP demo_last_request_duration_seconds Duration of the most recent completed request.') print('# TYPE demo_last_request_duration_seconds gauge') print(f'demo_last_request_duration_seconds {latency_seconds[-1]:.3f}') print('# HELP demo_transferred_bytes_total Bytes transferred since this process started.') print('# TYPE demo_transferred_bytes_total counter') print(f'demo_transferred_bytes_total {transferred_bytes}') print('# HELP demo_capacity_used_ratio Fraction of configured capacity currently used.') print('# TYPE demo_capacity_used_ratio gauge') print(f'demo_capacity_used_ratio {used_ratio}') 首行注释说明,转换后有三分之二的观测不超过零点三秒,而把毫秒数值直接当成秒时,三条都无法满足阈值。导出的最后请求耗时为零点六三秒,累计字节数为一百零四万八千五百七十六,容量使用比例为零点二五,在百分比界面上对应百分之二十五。三个数分别对应持续时间、累计大小与无量纲比例,不能因为都能画成曲线就混用。 ...

十月 30, 2026 · 1 分钟 · XB Field Notes
一至五秒的宽区间与一至两秒的窄区间,对同一个两秒原始 p99 给出不同估计:4.2 秒和 1.8 秒。

直方图保留延迟分布的形状

平均值可能让一个令人不舒服的服务看起来很快。如果九十五次请求各耗时五十毫秒,另外五次耗时两秒,平均延迟也只有一百四十七点五毫秒。直方图能够在不保存每条原始请求的情况下,保留更多关于这部分慢请求的信息。但它保存的是分桶后的分布近似,不是全部原始观测,也不会天然提供精确的分位数。理解这个区别,才能避免把计算输出当成重新测得的真实延迟。 同一组原文观测会因桶边界不同,产生不同的经典直方图估计。本样例中较窄桶减小了误差,但没有还原原始分位数。与边界对齐的阈值计数对已记录观测可以精确。标准指数型原生桶使用不同的插值模型。本轮没有重跑 Python 样例或其历史 Prometheus 对比。 先看桶里究竟统计了什么 在 Prometheus 经典直方图中,桶的边界标签表示小于或等于该上界的全部观测。计数具有累积性:一条五十毫秒的请求,既进入一百毫秒桶,也进入所有更大的桶。正无穷桶覆盖全部观测,计数和总和组件则分别记录样本数量与累计耗时。因此,直接把所有累积桶相加会重复统计请求,不能把结果当成真实访问量。 相邻累积桶相减,可以得到互不重叠区间内的观测数量,但仍然不知道每条请求在该区间中的具体位置。边界兼容的直方图可以先把对应桶的计数相加,再估计总体分位数。直接平均多个实例已经算出的分位数,无法恢复合并后的分布,即使各实例自己的分位数都计算得很精确,也不存在这种简单的总体换算关系。 分辨率决定答案能有多精细 对于常见的正数经典桶,分位数函数先定位目标排名所在的桶,再假定该区间内的观测均匀分布,执行线性插值。真实延迟却可能集中在桶的某一侧,所以返回值是与桶宽相关的估计,并不是被重新找回的实际观测。应该围绕业务真正关心的运行区间设置边界,而不是把大部分精度浪费在与目标无关的范围内。 如果桶边界正好位于三百毫秒目标上,就可以直接统计达到该延迟要求的请求数。这通常比观察一个插值得出的高分位数是否恰好低于阈值,更贴近事件型目标的定义。不过,经典直方图每增加一条边界,都会为每组标签组合增加桶序列。现代 Prometheus 也支持原生直方图,当前文档建议在埋点及相关系统支持时优先考虑;标准指数型原生桶采用不同的插值方式,下面的实验特意只讨论经典桶。 坏掉的样子 上层桶过宽时,少量观测移动就可能让尾部估计出现看起来很大的跳跃。经典分位数计算还要求存在正无穷桶,遗漏它可能使结果无效。如果目标排名落在最后的无限桶中,Prometheus 会返回前一个有限桶的上界,而不是编造一个无限延迟。上述输出都不能告诉你最慢那条请求的准确耗时,追查单次异常仍需要更细的观测材料。 空样本总体没有可解释的观测分位数。跨实例桶边界不匹配、同一指标混入不同单位,或者累积计数出现不合法的下降,也会破坏结果含义。按时间查询累计计数器时,应先计算合适的增量或速率,再聚合实例,使重置得到正确处理。另外,全请求分布也要说明结果范围:快速失败可能降低表面延迟,却同时让服务变得更不可用,不能仅凭曲线变快就宣布改善。 快速验证 保存为 histogram-shape.py,使用 Python 3 执行。程序先从人工构造的原始样本计算精确的最近秩高分位数,再分别根据两套经典桶估计相同分位点。精简插值函数只适用于这里的正数、非空样本,并断言选中的桶有有限边界;它用于展示桶内假设,不替代 Prometheus 对所有特殊输入和边界情况的完整实现。 ...

九月 20, 2026 · 2 分钟 · XB Field Notes