分位、延迟和正确的聚合:平均两个 P99 得不到全局 P99
实例 A 的 P99 是 1 秒、实例 B 的 P99 是 10ms,平均成 505ms——这个数字既不是 A 的也不是 B 的,更不是全局的。本页讲分位的不可加性、桶边界决定的精度上限,以及灰故障与亚稳态如何在"平均值正常"下持续失败。分位不可加的调用链推导见延迟预算与尾部放大;协调遗漏的压测偏差见P99、样本窗口和测量偏差。
分位数是特定样本集的统计
分位数是特定样本集的统计,不具备一般可加性。总链路 P99 不等于各阶段 P99 之和;串行阶段需要保留请求级关联才能解释尾部。窗口太短会抖动,太长会延迟发现。事件时间、采集时间和处理时间需区分;批量导出延迟可能令仪表盘在故障后才显示异常。告警应由用户影响、错误预算消耗或明确的资源饱和条件触发,且包含行动和负责人。只因 CPU 突增报警会造成噪声;没有覆盖用户失败的低 CPU 系统也可能严重故障。
为什么平均P99会误导扩容
实例A处理100个请求,99个1ms、1个1s;实例B处理9900个全部10ms。实例P99的定义/插值方式先需声明,但无论如何平均两个P99都没有反映请求权重与全局排序。全局分位需合并原始样本或兼容直方图桶,不能先算实例分位再做avg。
直方图桶边界决定近似精度。尾部只设1s和10s两桶时,不能宣称测得1.2s精确P99。summary的客户端分位通常不能跨实例合并;直方图计数/和也必须用同样标签、窗口和单位。诊断单次长请求依靠trace/log,而不是继续从聚合值反推唯一原因。参考Prometheus直方图与summary,实现时再核对部署版本及native/classic类型,不把两种查询拼接。
灰故障、级联与亚稳态
灰故障表现为部分请求、某个区域、某些租户或特定数据形态缓慢失败。单一健康端点可能持续返回成功,而关键业务路径已超时或卡在队列。级联故障由超时、重试、队列、资源争用和健康检查相互作用传播。局部故障可能导致上游线程耗尽,进而使恢复请求也无法通过。
诊断要把延迟、队列年龄、线程/连接占用、重试率、依赖状态、发布变更和数据差异放在同一时间线上。单个全局平均值和日志关键词无法证明根因。
采样窗口与期限违约
闭环客户端发送后等待响应,服务变慢时实际发压下降,恰好少测到最差时段。开环按计划到达更能展示排队,但要记录发送失败、丢弃与客户端自身瓶颈。超时请求被删除会使"成功请求P99"变漂亮,同时业务更差;成功与全部有效请求需分别统计。
假设稳定到达1000/秒、处理800/秒,60秒积压1.2万。只统计已完成请求不一定呈现后面队列的完整等待;窗口结束时未完成也必须计期限违约。把重试请求当新的用户样本则会改变权重。
实验与方案比较
用两个已知样本数组,手工排序求nearest-rank分位,再比较分位平均值;随后离散进直方图,解释近似误差。第二组加入超时和未完成样本,对照仅成功与业务期限的不同报告。这些演算可在纸面或脚本完成,标为"计算验证";真实监控查询本轮未运行。
方案A细桶全保留,精确度较高但时序和存储成本更高;方案B少桶加错误/慢请求追踪,适合预算受限但要承认近似区间。评审给出业务阈值附近的桶设计,而不是固定"所有服务相同桶"。
聚合口径检查表:平均 P99、桶与窗口三件事先对齐
本页前面用实例 A/B 说明了平均 P99 没有意义,评审时还需要一张能逐项打勾的检查表,否则同一张看板在不同人手里会得出不同结论。
检查表四项:同一总体(哪些实例、哪些租户、哪些路由进入这张图)、同一单位(毫秒还是秒、请求还是批次)、同一窗口(起止时刻与对齐方式)、同一算法(最近秩、插值还是直方图桶)。任一项不一致,比较与合并都不成立。补一项第五检查:样本量是否足够——P99 在 230 个样本以下没有意义,这一条在容量主题(U70 分位样本量)已单独推导,本页只引用不重复。
用本页的 A/B 算例复核:实例 A 处理 100 个请求(99 个 1ms、1 个 1s),实例 B 处理 9,900 个全部 10ms。两个 P99 直接平均得 (1,000+10)/2=505ms;把 10,000 个样本合并排序后,最近秩 P99 位置是第 9,900 个,值为 10ms。505ms 既不描述 A 也不描述 B,更不是全局——它只是两个统计量的算术平均。
灰故障的聚合检查还要多一步:按数据形态分层。若 0.1% 的超大 payload 请求全部超时,全局 P99 可能只升 2ms,但这类请求的成功率是 0。检查表要加"已知灰故障形态是否单独分层"一项,列出当前分层维度与未覆盖形态。
执行 python3 labs/observability_models.py aggregation_checks:预期输出 naive_average_ms=505.0、global_p99_ms=10、samples=10000,五项检查全为 true。脚本只验证合并算法与算例,不查询真实监控;Prometheus histogram_quantile 的实跑见 U64。
两个合理选择:A 每个实例各自发布 P99,简单但无法回答全局;B 发布兼容直方图桶、由查询端按同窗口合并后再算分位,成本高但可聚合。本例选 B,并规定任何跨实例比较必须先通过检查表四项,否则只允许并列展示,不允许写成一个全局数字。
架构师变化条件
把 SLO 从 200ms 收紧到 100ms:桶边界必须围绕 100ms 加密,否则 SLO 边缘变化不可见;历史直方图与新城重不兼容,切换窗口要声明。若灰故障集中在单一数据形态(如超大 payload),全局分位看不到它,需要按形态分层指标。亚稳态恢复期把重试率加入同一时间线,避免把"处理恢复"误读为"队列恢复"。每次变化重画分层与桶设计。
闭卷验收
本页 8 道闭卷题收进了下方自测面板:先回忆,再展开参考答案与评分点,最后给三档自评。