晚上七点的火锅店,你拿到一张“前方还有23桌”的等位号。隔壁桌运气好,5分钟就入座了;而在大厅角落,有一桌客人度日如年地等了一个半小时,最后骂骂咧咧地摔门而去。如果店长当晚算一笔账:所有客人平均等了28分钟——“嗯,不算太久嘛!” 但真相是:一半客人15分钟内就坐下了,四成客人等了半小时以上,还有5%的倒霉蛋等了超过一个钟头。平均28分钟,没有告诉你任何一位真实客人的体感。 AI服务的推理延迟,和这张等位榜单一模一样。一次“推理请求”从发出到拿到结果,中间隔着模型排队、显存调度、GPU计算、网络传输。记录一千次请求的耗时,算个平均值,得到的只是“28分钟”式的安慰。真正能读懂性能分布的是分位数:P50告诉你一半请求有多快,P95告诉你绝大多数人的感受,P99则永远揪着那慢到离谱的1%不放。这张“等位榜单”,才是运维AI服务的店长真正该盯的东西。本文就用火锅店的故事,带你从零读懂这套数字背后的逻辑。

岗位关联

读懂了P50/P95/P99,你就掌握了把“感觉服务慢”翻译成“数字证据”的看家本领——这是AI服务SRE、ML平台工程师实战与面试的必修技能。

目录
  1. 可视化演示
  2. 延迟分位数基础
  3. 分位数计算方法
  4. P50典型体验
  5. P95多数感受
  6. P99极限体验
  7. 采集方案设计
  8. SLI/SLO设定
  9. 延迟异常诊断
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示AI推理服务延迟分布直方图与P50/P95/P99百分位实时追踪,帮助定位长尾延迟问题。

本节配有交互动效(进入视口后自动加载,约 3KB)。

推理延迟P50/P95/P99 P50中位数:50%请求低于此延迟 P95长尾:95%请求低于此延迟 P99极端:99%请求低于此延迟 P99 ≫ P95 ≫ P50 → 长尾延迟问题 百分位延迟监控定位推理性能瓶颈

延迟分位数基础

店长想搞明白“客人到底要等多久”。他没问平均等了多长,而是翻出昨晚的200张等位小票,按从短到长排成一排。第100张是“一半人的真实体验”,第190张是“绝大多数人熬到的关口”。这种“按顺序找位置”的方法,就是分位数思想的雏形。

推理服务的延迟数据也长着一张“长尾脸”:绝大多数请求几十毫秒内返回,偶尔几个请求因为排队、显存争抢、网络抖动拖到几秒。算术平均被这几个极端值一拉,立刻“报喜不报忧”——明明九成用户很顺畅,均值却显得很难看。分位数则按位置切割数据,P50、P95、P99分别代表50%、95%、99%的请求都低于该延迟值,就像把200张票按名次切成三段,每段各有各的代言人。

定义分位数最直接的方法是最近秩法(nearest-rank):

店长把200张票按时间排序,数到第 pN 张,就拿到了他要的答案——分位数并不神秘,它就是长队里那把“第多少位”的尺子。

Q^p=x(⌈p×N⌉)\displaystyle \hat{Q}_{p}=x_{(\lceil p \times N\rceil)}
  1. 排序样本把 N 次请求的延迟从短到长排成有序序列,得到 \(x_{(1)} \le x_{(2)} \le \cdots \le x_{(N)}\)。
    x(1)≤x(2)≤⋯≤x(N)\displaystyle x_{(1)}\le x_{(2)}\le\cdots\le x_{(N)}
  2. 计算排名p 分位对应的名次,用天花板函数向上取整。
    rank=⌈p×N⌉\displaystyle \text{rank}=\lceil p \times N\rceil
  3. 取出对应值排名所对应的那一个样本延迟值,就是该分位数。
    Q^p=x(⌈p×N⌉)\displaystyle \hat{Q}_{p}=x_{(\lceil p \times N\rceil)}

分位数计算方法

打烊后,领班拿着200张等位小票想算“95%的人都等了多久”。最省事的答案是:200×0.95=190,找到从短到长排在第190位的票,这就是P95。可隔壁分店却习惯把第190位和第191位再做一次平均,两家店算出的数字略有出入。谁对?其实都对,只是算法约定不同。

工程上同样存在两类主流算法。最近秩法简单直观、适合快速估算;线性插值法则像在两把椅子之间垫了个斜坡,让分位点随样本量平滑变化,在 SLO 这类对精度敏感的"99.9%"指标上更稳。NumPy 的默认分位数计算用的就是线性插值:

两种算法在样本量大时结果相差无几,但插值法在数据集较小时更稳定。火锅店两家分店吵了一晚上,最后发现:只要约定统一,账怎么算都对。

Q(p)=(1−γ)xj+γxj+1,j=⌊(N−1)×p⌋, γ=(N−1)×p−j\displaystyle Q(p)=(1-\gamma)x_{j}+\gamma x_{j+1},\quad j=\lfloor (N-1)\times p\rfloor,\ \gamma=(N-1)\times p-j
  1. 计算位置 h把百分位 p 映射到从 0 到 N-1 的坐标轴上。
    h=(N−1)×p\displaystyle h=(N-1)\times p
  2. 拆成整数与小数j 是整数部分,γ 是小数部分,表示“夹在两位样本之间”的精确位置。
    j=⌊h⌋,γ=h−j\displaystyle j=\lfloor h\rfloor,\quad \gamma=h-j
  3. 加权平均两个相邻样本按距离权重相加,距离近的贡献大。
    Q(p)=(1−γ)xj+γxj+1\displaystyle Q(p)=(1-\gamma)x_{j}+\gamma x_{j+1}

P50典型体验

店长每天早上开晨会,最先看的是“第100张小票”——P50。因为一半客人比这张票快,一半比它慢,这就是“正常运气”的客人体验到的等待时长。对AI服务来说,P50就是那个“典型用户”感受到的响应速度。

P50最大的优点是抗离群值。哪怕有100个请求因为故障拖到2秒,只要大多数请求在50毫秒附近,P50就岿然不动。反观平均值,一个极端值就能把它拉高几十毫秒,让你误以为系统全面变慢。这正是中位数的统计魅力:它描述“中心”,却不被“意外”绑架。

在工程里,P50是容量规划的基准线:QPS 翻倍时 P50 是否上移,直接告诉你系统还有多少余量。它是店长口袋里的体温计——不发烧不代表没毛病,但发烧一定说明出问题了。

P50=x(N+12)\displaystyle P_{50}=x_{\left(\frac{N+1}{2}\right)}
  1. 定位中间位置样本数为 N 时,中位数排在正中间。
    rank=N+12\displaystyle \text{rank}=\frac{N+1}{2}
  2. 奇偶样本取值N 为奇数时取中间那一个样本,N 为偶数时取中间两个样本的平均。
    P50=x(N/2)+x(N/2+1)2(N 为偶数)\displaystyle P_{50}=\frac{x_{(N/2)}+x_{(N/2+1)}}{2}\quad(N\ \text{为偶数})

P95多数感受

周五晚上是火锅店最忙的时候,店长最关心一台数据:95%的客人都等到了哪一张票。因为第190位(95%)客人即使最后坐下了,也多半在抱怨“等太久了”。P95 代表的不是运气最好的人,而是“开始不耐烦但仍然留下”的临界体验。

AI服务里,P95 是用户体感的分水岭。它告诉你:每 20 个请求里就有 1 个比它还慢。对于搜索、推荐这类高并发产品,那 5% 的慢请求就是用户流失的暗流。长尾效应的来源很多:热点请求争抢算力、GPU 显存碎片化、冷启动的模型实例、突发的网络抖动,它们共同把尾巴拖得又粗又长。

P95 与 P50 的距离,是衡量这条尾巴有多肥的直观指标:

如果 \(\Delta_{95}\) 持续变大,就说明系统在“悄悄积累慢请求”。店长看到“第190位客人等了40分钟”时,心里立刻有数:不是某位客人倒霉,而是晚市的排队机制出了问题——该加桌了。

Δ95=P95−P50\displaystyle \Delta_{95}=P_{95}-P_{50}
  1. 读出两个分位点分别取 P50 和 P95 的延迟值。
    P50,P95\displaystyle P_{50},\quad P_{95}
  2. 做差得到尾部距离差值越大,说明长尾越肥,极端等待越普遍。
    Δ95=P95−P50\displaystyle \Delta_{95}=P_{95}-P_{50}

P99极限体验

总有那么1%的客人,等得花儿都谢了。他们要么是午夜最后一桌,要么是碰到传菜员摔了一跤。P99 就是这“最倒霉1%”的等待时长。店长对这条线又爱又恨:它平时安静如鸡,一旦爆发,就是差评与退单的前奏。

P99 极其敏感。GPU 上偶发的任务抢占、一次跨可用区的网络重路由、某台机器上的 GC 停顿,都会在 P99 上留下明显尖峰,而 P50 可能纹丝不动。更危险的是连锁反应:客户端设了 800ms 超时,P99 一旦超过它,就会有一批请求超时后自动重试,重试又加剧负载,把更多请求推进慢速队列——这就是经典的“重试风暴”。值得注意的是,P99 并不等于最大值,那最慢的 1% 里完全可能有比 P99 慢十倍二十倍的“怪物请求”。

P99 与 P50 的比值,是判断系统尾部有多畸形的指标:

健康的系统 T 值通常在 3~5 之间;超过 10 就该立刻排查。店长知道,那1%的客人虽然人数少,却最可能把差评发到点评网上——P99,就是差评的预警线。

Tratio=P99P50\displaystyle T_{ratio}=\frac{P_{99}}{P_{50}}
  1. 读出 P99找到第 99% 位的延迟值,代表最慢的 1% 的门槛。
    P99\displaystyle P_{99}
  2. 读出 P50用它作为“正常体验”的基准。
    P50\displaystyle P_{50}
  3. 相除得到尾部比比值越大,说明极端越极端,健康度越差。
    Tratio=P99P50\displaystyle T_{ratio}=\frac{P_{99}}{P_{50}}

采集方案设计

靠谱的店长会在发号机上记下“拿号时间”,客人入座时服务员再扫一下“叫到时间”,两者之差就是真实等待时长。想算分位数,第一步永远是:把每个请求的开始和结束时刻都记下来。

但推理服务每秒可能处理几千个请求,如果每个请求都存一条精确到毫秒的完整日志,一天的存储量就是天文数字。工程上最常用的方案是分桶直方图(bucketized histogram):把延迟范围切成若干区间(如 0-10ms、10-20ms…),内存里只维护每个桶的计数,不落原始数据。计算 P95 时,从低桶往高桶累加计数,找到第一个累计值越过 95% 样本数的桶,再做桶内插值:

桶宽越细精度越高,内存占用越大,因此实践中常配合 10 秒或 1 分钟的滚动窗口,边聚合边丢弃旧数据。这就像火锅店用“等位时段统计表”代替逐张保留小票:丢掉细节,留下形状,足够店长做决策了。

Qp=L+k−Cf×w\displaystyle Q_{p}=L+\frac{k-C}{f}\times w
  1. 选定目标桶从低位往高位累加,找到包含第 k 个样本的桶,L 是该桶下界,桶宽为 w。
    L≤Qp<L+w\displaystyle L \le Q_{p} < L+w
  2. 读取桶内参数f 是本桶样本数,C 是本桶之前所有桶的累计样本数。
    f,C\displaystyle f,\quad C
  3. 桶内等比例插值按 \((k-C)/f\) 的比例在桶内推进,得到分位数近似值。
    Qp=L+k−Cf×w\displaystyle Q_{p}=L+\frac{k-C}{f}\times w

SLI/SLO设定

店长在门口挂了一块牌子:“95% 的客人,15 分钟内上桌。” 这句话翻译成工程语言就是 SLO——对服务质量的白纸黑字承诺。客人不会去读平均等位时间,他们只关心“我到底要等多久”,所以承诺必须用分位数来表达。

先区分两个容易混淆的词:SLI(Service Level Indicator)是实际测量的指标,比如“最近5分钟请求的P95延迟”;SLO(Service Level Objective)是为 SLI 设定的目标值,比如“P95 ≤ 500ms,且一个季度内 99% 的时间满足”。有了 SLO,还要留出“允许犯错的空间”,这就是误差预算(error budget):

比如一个月约 43200 分钟,99% 的 SLO 意味着每月最多允许 432 分钟“超标”。预算快用完时,就该冻结新功能、加大排查力度。店长的承诺牌也一样:只要这个月“15分钟上桌”的达标率跌破 95%,他就得停掉招牌菜的推广,专心把后厨理顺。

Budget=window×(1−SLO)\displaystyle \text{Budget}=\text{window}\times(1-\text{SLO})
  1. 写出 SLO 百分比比如 99%,代表承诺达标的比例。
    SLO=0.99\displaystyle \text{SLO}=0.99
  2. 算出失败率上限1 减去 SLO,就是允许不达标的比例。
    1−SLO=0.01\displaystyle 1-\text{SLO}=0.01
  3. 乘以窗口时长得到在统计窗口内可以容忍的错误时长。
    Budget=window×(1−SLO)\displaystyle \text{Budget}=\text{window}\times(1-\text{SLO})

延迟异常诊断

某个周五,店长发现平板上的报表很蹊跷:平均排队时间还是30分钟,P50 也正常,但“最惨客人等待时长”从40分钟飙到了 3 小时。他立刻警觉:不是整体变慢,而是某个环节出现了偶发的大故障——可能是三号锅坏了,也可能是新来的传菜员总在忙时迷路。

诊断延迟异常,第一步是看分位数的形态组合:P50 和 P95 同升,通常是整体负载过高,需要扩容或限流;P50 平稳而 P99 飙升,则指向偶发抖动或资源争抢。为了量化变化,可以计算当前分位数与窗口前值的差:

第二步是多维归因:把请求按实例、模型版本、输入长度切片,分别计算 P99,找出最异常的维度。第三步是根因定位与修复:GC 停顿就调整堆参数,GPU 争抢就错峰调度,批大小波动就改用动态批处理。店长最终发现是三号电磁炉的温控器坏了,导致那一桌的菜总是慢半小时——换掉温控器,P99 立刻回落。诊断的本质,就是把“总有人倒霉”变成“倒霉在哪一桌、哪口锅”。

ΔP99(t)=P99(t)−P99(t−w)\displaystyle \Delta P_{99}(t)=P_{99}(t)-P_{99}(t-w)
  1. 取当前值得到本窗口内 P99 的延迟值。
    P99(t)\displaystyle P_{99}(t)
  2. 取窗口前值得到 w 个时间窗之前的 P99 基线。
    P99(t−w)\displaystyle P_{99}(t-w)
  3. 做差得增幅差值越大,说明尾部恶化越快,越需紧急介入。
    ΔP99=P99(t)−P99(t−w)\displaystyle \Delta P_{99}=P_{99}(t)-P_{99}(t-w)

AI 应用场景

LLM 对话服务的 SLO 监控

阶段:模型部署与线上监控阶段

解决的问题:只看平均首 Token 延迟,用户“卡顿感”其实由尾部决定。传统监控用均值反映整体,但 LLM 生成受排队、显存争用影响极大,P95/P99 才能真正区分“普遍变慢”和“个别超时”。

具体案例:某智能客服 LLM 服务,每 5 秒聚合一次延迟直方图,SLO 设定为“P95 首 Token ≤ 800ms”。某天 P99 连续 3 个窗口超过 1200ms,按实例切片后发现单张 GPU 因显存碎片频繁调度抖动,迁移该实例后恢复。P50 始终正常,正是分位数组合救了这次排查。

推荐系统的容量规划

阶段:容量评估与扩缩容决策阶段

解决的问题:P50 低不代表扛得住高峰,均值回放会掩盖峰值体验恶化。用 P95/P99 评估真实用户体验,才能给出科学的扩容信号。

具体案例:晚高峰时推荐服务 QPS 翻倍,P50 仍稳定在 50ms,但 P95 从 120ms 涨到 400ms。团队以"P95 ≤ 250ms"为扩容触发线,提前完成弹性扩容,避免用户在高峰期感受到的明显卡顿,同时节省了非高峰期的算力成本。

语音助手服务的异常诊断

阶段:故障排查与根因分析阶段

解决的问题:P99 毛刺频发但平均延迟正常,抖动来源难以定位。分位数多维归因能快速锁定“最慢请求”所在的实例与资源维度。

具体案例:某 ASR 语音识别服务 P99 从 2s 飙至 8s,按实例维度拆解后发现某批新机型 CPU 虚拟化争抢严重,P95 却几乎不受影响。团队将这批实例的调度策略改为低优先级混合部署,P99 回到 2.3s。

Python 演示

python52 行
"""推理延迟 P50/P95/P99 分位数计算演示"""import mathimport random  def simulate_latencies(n=1000):    """模拟 LLM 推理延迟: 主体 60-150ms, 偶发长尾到 2s"""    latencies = []    for _ in range(n):        r = random.random()        if r < 0.75:            v = 60 + 90 * r / 0.75        else:            v = 150 + 1850 * ((r - 0.75) / 0.25) ** 2        latencies.append(round(v, 1))    return latencies  def percentile_nearest_rank(data, p):    """最近秩法: 排序后取第 ceil(p*N) 个样本"""    ordered = sorted(data)    rank = math.ceil(p * len(ordered)) - 1    return ordered[rank]  def percentile_linear(data, p):    """线性插值法: 与 NumPy 默认方式一致"""    ordered = sorted(data)    h = (len(ordered) - 1) * p    j = int(math.floor(h))    gamma = h - j    return (1 - gamma) * ordered[j] + gamma * ordered[j + 1]  def main():    random.seed(42)    lat = simulate_latencies(1000)    avg = sum(lat) / len(lat)    p50 = percentile_nearest_rank(lat, 0.50)    p95_n = percentile_nearest_rank(lat, 0.95)    p95_l = percentile_linear(lat, 0.95)    p99 = percentile_nearest_rank(lat, 0.99)    print(f"请求总量: {len(lat)}")    print(f"平均延迟: {avg:.1f} ms, 是 P50 的 {avg / p50:.2f} 倍")    print(f"P50(最近秩): {p50:.1f} ms")    print(f"P95(最近秩): {p95_n:.1f} ms | 线性插值: {p95_l:.1f} ms")    print(f"P99(最近秩): {p99:.1f} ms")    print(f"P99/P50 尾部比: {p99 / p50:.1f}")  if __name__ == "__main__":    main()
目的:模拟 1000 次推理请求的延迟,用最近秩法和线性插值法分别计算 P50/P95/P99,并对比平均值与分位数的差异,演示分位数在长尾分布下如何揭示真实体验。
  1. lat = simulate_latencies(1000)生成 1000 个带长尾的模拟延迟样本,贴近真实推理服务的分布形态。
  2. ordered = sorted(data)分位数的第一步永远是排序,只有排好队才能数名次。
  3. rank = math.ceil(p * len(ordered)) - 1最近秩法:向上取整得到名次,减 1 转成 Python 列表索引。
  4. h = (len(ordered) - 1) * p; gamma = h - j线性插值法的关键拆解:位置分解为整数部分和小数部分。
  5. print(f"平均延迟: {avg:.1f} ms, 是 P50 的 {avg / p50:.2f} 倍")直观看到均值被长尾拉偏了多少,体会“为什么不能只看平均”。

常见误区

误区“P99 是 0.99 秒?那只要 P99 小于超时时间,就不会有请求超时了。P99 不就是最慢的那个请求吗?”

正解P99 只承诺“99% 的请求快于它”,剩下那 1% 可能远比它慢得多。就像火锅店说“95% 的客人 15 分钟内入座”,不代表没人等过两小时。真正的极值要看最大值或更高的分位如 P99.9,P99 与 max 之间可能隔着一条鸿沟。

为何常见:直觉上“99%“已经非常接近”全部“,人们容易把”绝大多数“和”所有“混为一谈,忽略了尾部本来就意味着”没被包含的那一小撮”。

误区“看平均延迟多简单,一个数字就能代表整体水平,用分位数还得排序还要解释,太麻烦。”

正解长尾分布下均值会被极端值严重拉偏。设想 50 个请求 5ms、1 个请求 10s,平均约 200ms,而 P50 只有 5ms——P50 才代表大多数用户的真实感受。SLO 与容量规划场景几乎都基于分位数,因为均值天然“报喜不报忧”。

为何常见:我们从小习惯用“平均分”衡量成绩,统计课的第一直觉就是均值,忽略了它只适合对称分布,而延迟几乎总是偏斜的。

误区“既然要算 P99,那就把所有请求的延迟都存下来,保证精确,别用什么近似的桶。”

正解高吞吐推理服务每秒上万请求,全量保存每个时间戳的存储与查询成本极高。分桶直方图在内存里以固定桶数聚合,支持多节点合并、滚动窗口、桶内插值,精度损失可控。监控的目的是“看出趋势”而非“归档档案”。

为何常见:担心近似计算会失真,却忽略了规模化成本;实际上 P99 本身的统计属性就带有估计性质,差几个毫秒并不影响决策。

误区“P99 都上去了,把 SLO 定成 99.99%,用户一定满意,老板一定夸。”

正解越高的 SLO 意味着越苛刻的技术要求和成本,还会触发大量无效告警,让团队疲于奔命。合理做法是选择用户可感知的 P95 作为对外承诺,把 P99 当作内部健康信号,用误差预算决定发布节奏。承诺越紧,违约的代价越重。

为何常见:把“技术指标越高越好”当作铁律,忽略了 SLO 的本质是商业承诺——它必须和用户体验、工程成本形成平衡。

面试题

Q1. 关于推理延迟的 P50(中位数),下列说法正确的是?

单选题 · easy

  • A.代表所有请求的算术平均耗时
  • B.表示 50% 的请求快于该延迟值← 正确答案
  • C.总是大于等于平均延迟值
  • D.表示最慢的那一半请求耗时

答案:B。P50 是排序后位于中间位置的延迟值,表示一半请求比它快、一半比它慢。它不是均值,也不总大于均值——长尾分布下通常均值更大,但这不是定义。B 准确描述了分位数的本质含义。

Q2. 评估推理性能时,为什么 P50 比平均值更有参考价值?

单选题 · easy

  • A.平均值计算过程太复杂耗时
  • B.平均值容易被极小数值拉低
  • C.平均值会被长尾极值严重拉偏← 正确答案
  • D.平均值无法从日志中获取到

答案:C。推理延迟呈长尾分布,少数极慢请求会把平均数拉高,造成“整体很慢”的假象。P50 抗离群值,代表典型用户体验。平均值不难算也可以从日志拿,但它在偏斜分布下没有代表性。

Q3. 用最近秩法求 P99,1000 个样本对应的排名位置是?

单选题 · mid

  • A.第 990 个样本对应的延迟值← 正确答案
  • B.第 99 个样本对应的延迟值
  • C.第 999 个样本对应的延迟值
  • D.第 9900 个样本对应的延迟值

答案:A。最近秩法公式为 \(\lceil p \times N\rceil\),代入 p=0.99、N=1000 得 rank=990,即排序后第 990 个样本的延迟值就是 P99。注意是“第 990 个”而不是“第 99 个”,排名是从 1 开始数的。

Q4. 某 AI 服务将 SLO 设为"P95 ≤ 500ms",其含义是?

单选题 · mid

  • A.平均延迟永远不超过 500 毫秒
  • B.95% 的请求延迟不超过 500 毫秒← 正确答案
  • C.500 毫秒内必须完成全部推理
  • D.P99 延迟不得超过 500 毫秒

答案:B。SLO 描述的是对 SLI 的目标承诺,"P95 ≤ 500ms"表示在统计窗口内,95% 的请求延迟都要低于 500ms,剩余 5% 可超时。它不承诺平均值、不承诺全部请求,也与 P99 无关。

Q5. 分桶直方图统计延迟数据的主要好处是?

单选题 · mid

  • A.能精确保存每个请求的延迟值
  • B.占用固定内存且支持高效聚合← 正确答案
  • C.可以完全替代原始日志的存储
  • D.保证分位数结果绝对精确无误

答案:B。分桶直方图只维护各桶计数,内存占用与桶数成正比而与请求量无关,支持多节点合并和滚动聚合。代价是分位数需要桶内插值近似,并不“绝对精确”,也无法还原每个请求的原始值,但它足够支撑监控决策。

Q6. P50 保持平稳但 P99 显著上升,最可能的原因是?

单选题 · hard

  • A.系统整体请求量出现均匀增长
  • B.模型推理普遍变慢了一个档次
  • C.少数请求遭遇毛刺或资源争抢← 正确答案
  • D.所有请求延迟同步增加了等量

答案:C。P50 平稳说明大多数请求体验未变,P99 上升说明只有最慢的 1% 明显恶化,典型于偶发的资源争抢、GC 停顿、网络抖动等毛刺。若整体均匀变慢,P50 会同步上升;整体过载时 P50/P95/P99 通常会一起抬升。

Q7. 关于误差预算(error budget)的说法正确的是?

单选题 · mid

  • A.预算耗完说明服务没有任何问题
  • B.等于 1 减去 SLO 目标的百分比← 正确答案
  • C.表示可以随意丢弃的请求比例
  • D.只适用于 P99 而不适用于 P95

答案:B。误差预算 = \(1-\text{SLO}\),表示在统计窗口内允许不达标的时间或比例。预算耗尽意味着服务在本周期内已无违约空间,应停止高风险变更并优先修复。它与 P95/P99 都可用,是 SLO 管理中的通用工具。

Q8. 常用的推理延迟分位数采集方案有哪些?

多选题 · easy

  • A.埋点记录请求开始与结束时间戳← 正确答案
  • B.服务端按固定窗口聚合延迟直方图← 正确答案
  • C.对全部样本做精确排序再存库
  • D.按时间窗口取最小延迟作为代表

答案:AB。埋点拿原始耗时数据、分桶直方图做内存聚合,是标准组合。全量精确排序在每秒上万请求的流量下存储代价过高;取最小值完全丢失了尾部信息,无法反映真实体验,属于错误做法。

Q9. P99 延迟过高可能引发哪些连锁后果?

多选题 · hard

  • A.客户端提前超时并对请求发起重试← 正确答案
  • B.重试放大导致服务负载进一步升高← 正确答案
  • C.P50 一定会随之同步急剧地升高
  • D.所有用户都会立即感知到服务卡顿

答案:AB。P99 过高会突破客户端超时阈值,触发重试;重试请求再次进入队列,放大负载甚至雪崩。但 P50 不一定升高,因为只有尾部少量请求受影响;“所有用户”也夸大其辞——体感受损的是那 1% 的请求及其关联用户。

Q10. 排查延迟异常时,合理的多维归因维度包括?

多选题 · extreme

  • A.按实例维度对比各副本的 P99← 正确答案
  • B.按输入长度或批次大小分组看 P99← 正确答案
  • C.按请求数量平均值替代分位分析
  • D.只观察全天平均延迟的变化趋势

答案:AB。按实例、模型版本、输入长度切片计算分位数,是定位“慢在哪一桌”的关键手段。用平均值替代分位数会掩盖尾部恶化,只看全天平均趋势则根本发现不了 P99 尖峰——这正是分位数诊断与均值监控的本质区别。