5.7 噪声底线与回归检测
上一节:5.6 统计基础 | 下一节:5.8 实验记录与常见反模式 配套代码:05-experiment-design/07-noise-floor-and-regression 本节是本章的核心。 它回答一个问题:在你的环境里,多大的差异才算「真实差异」?
一句话结论
噪声底线 = 在代码完全不变的情况下,你重复实验能得到多大的差异。 它是你判断一切性能结论的标尺:低于噪声底线的"优化",无论听起来多合理,都无法被你的数据证实。
一、用「体重秤的精度」理解噪声底线
你家的体重秤有 ±0.5 kg 的误差。今天称是 70.0 kg,明天是 69.7 kg。
你能说「我减了 0.3 kg 吗?
不能——因为 0.3 kg 小于秤的精度。
正确说法:「在秤的精度范围内,体重没有变化。」
性能实验完全一样:
如果你的环境噪声底线是 ±8%:
P99 从 210ms 到 198ms(-5.7%) → ❌ 无法确认
P99 从 210ms 到 150ms(-28.6%)→ ✅ 可以确认
关键:噪声底线不是「你可能做到多精确」,而是「你的工具实际有多精确」。它由环境(云主机、后台任务、GC 抖动)决定,不由你的意愿决定。
二、怎么测噪声底线(六步)
① 冻结一切:代码、数据、负载、环境、观测配置全部不变
② 重启服务(确保从同一初始状态开始)
③ 完整跑一次实验(含预热),记录 P50/P95/P99、QPS、错误率
④ 重复 5–10 次(每次都重启 + 预热)
⑤ 计算每个指标的均值、标准差、CV
⑥ 定义噪声底线 = 该指标的最大波动范围
关键要求
| 要求 | 为什么 |
|---|---|
| 代码一字不改 | 否则测的不是噪声 |
| 每次都重启服务 | 否则上一轮的热状态会影响下一轮 |
| 至少 5 次 | 3 次看不出分布形态,5 次能看出基本范围 |
| 记录每一轮的值 | 不只看 CV,还要看是否有趋势(是否在变好/变坏) |
输出示例
═══ 噪声底线测量(10 轮,代码未改动)═══
轮次 QPS P50 P95 P99 错误率
1 498.2 32.1 68.4 93.2 0.00%
2 499.1 33.0 70.2 96.1 0.00%
3 497.5 32.4 67.9 94.0 0.00%
4 498.8 34.2 74.1 103.5 0.00% ← 偏高
5 499.4 32.8 69.3 95.2 0.00%
6 498.0 32.5 68.8 94.4 0.00%
7 499.7 33.1 70.5 96.8 0.00%
8 498.3 32.9 69.1 95.0 0.00%
9 499.2 32.6 68.2 93.8 0.00%
10 498.6 33.3 71.0 97.2 0.00%
指标 中位数 最小值 最大值 波动范围 CV
QPS 498.8 497.5 499.7 ±0.22% 0.13%
P50 32.8 32.1 34.2 ±3.2% 1.8%
P95 69.2 67.9 74.1 ±4.5% 2.7%
P99 95.1 93.2 103.5 ±5.4% 3.1%
═══ 结论 ═══
噪声底线(取最大波动范围的 1.5 倍作为安全边际):
QPS : ±0.3%
P50 : ±5%
P95 : ±7%
P99 : ±8%
含义:低于以下差异的结论,在本环境中不可信:
优化声称 P99 改善 < 8% → 无法确认
优化声称 P50 改善 < 5% → 无法确认
三、噪声底线的三个用处
用途一:判断「优化是否可信」
优化前 P99 中位数 = 210 ms
优化后 P99 中位数 = 195 ms
差异 = -7.1%
噪声底线 = ±8%
结论:❌ 差异在噪声范围内,无法确认优化有效
注意:这不是说「优化无效」,而是说「你的数据不足以证明它有效」。可能需要:
- 增加轮数(降低统计误差);
- 改善环境(降低噪声);
- 或者寻找差异更大的优化点。
用途二:设定 CI 门禁阈值
第 8 章会用到:
门禁阈值 = 噪声底线 × 安全系数(通常 1.5–2)
例:噪声底线 ±8% → 门禁阈值设为「恶化超过 12% 才告警」
为什么不能设成噪声底线本身:那样会有 50% 的误报率(噪声正好跨过阈值)。
用途三:判断「环境是否可用」
如果 CV > 10%:
→ 环境不适合做精细的性能对比
→ 先解决环境问题(第 4 节),或只做大颗粒度的判断(> 30% 的差异)
四、一个必须警惕的现象:趋势漂移
10 轮数据如果呈现单调趋势(比如 P99 一直在缓慢上升),那不是噪声——那是环境在变化:
轮次: 1 2 3 4 5 6 7 8 9 10
P99: 93.2 94.1 95.0 95.8 96.5 97.2 98.0 98.9 99.5 100.2
└──────────────── 持续上升 ────────────────┘
可能原因:
| 原因 | 怎么确认 |
|---|---|
| 数据量在增长(压测写了数据) | 检查表行数 |
| 缓存逐渐被污染/驱逐 | 检查命中率趋势 |
| 内存泄漏 | 检查堆基线趋势(第 3 章 3.5) |
| 机器发热降频 | 检查 CPU 频率 |
| 其他服务开始占用资源 | 检查系统负载 |
处理:先解决漂移,再测噪声底线。有漂移的环境测出的噪声底线是不可信的。
另一种漂移:如果做了写操作,数据量会持续增长——这是压测设计问题(第 4 章 4.1 节提到的数据隔离)。
五、回归检测:把噪声底线变成门禁
什么是回归检测
每次代码变更后,自动对比性能指标与基线:
如果指标恶化超过阈值 → 告警/失败
否则 → 通过
这是第 8 章「持续化」的基础,而阈值必须来自噪声底线。
回归检测的三个设计要点
| 要点 | 说明 |
|---|---|
| 相对比较,不是绝对阈值 | 与仓库中的基线比,而不是硬编码的数字 |
| 阈值 = 噪声底线 × 1.5–2 | 阈值必须高于噪声,否则天天误报 |
| 只对稳定指标设门禁 | max、P999 波动太大,只做趋势观察 |
一个真实的误报代价
阈值设置不当(等于噪声底线):
→ 每天 3–5 次误报
→ 工程师开始认为"这个门禁不可信"
→ 出现真问题时也无人处理
→ 门禁实际上已经失效
结论:宁可漏报,不可误报。
六、从噪声底线到「最小可检测差异」
最小可检测差异(MDD)≈ 噪声底线 × 2
理由:
优化前的值本身有 ±N 的噪声
优化后的值本身也有 ±N 的噪声
两者相减,噪声可能叠加到 ±2N
所以:
噪声底线 ±8%
→ 最小可检测差异约 16%
含义:只有声称"改善了 16% 以上"时,你的数据才有足够的说服力。
声称 10% 的改善,可能是真的,但你的环境证明不了。
这是一个残酷但重要的数字:如果你的环境噪声底线是 ±8%,那么所有 10% 以内的优化,你都只能"相信"而不能"证明"。
怎么办(三个方向):
| 方向 | 做法 | 代价 |
|---|---|---|
| 降低噪声 | 独占机器、绑核、固定频率、减少后台任务 | 环境成本 |
| 增加样本 | 多轮实验 + 统计检验 | 时间成本 |
| 增大效应 | 找差异更大的优化点(通常是更上游的瓶颈) | 需要重新定位 |
通常第三个方向最有效:与其纠结 5% 的常数优化,不如去找那个占 P99 50% 的环节(第 1 章 1.3 节的延迟分解)。
七、本节小结
- 噪声底线 = 代码不变时重复实验的差异范围。它是判断一切性能结论的标尺。
- 测量方法:冻结一切 → 重启 → 完整跑 → 重复 5–10 次 → 算 CV 与波动范围。
- 低于噪声底线的"优化"无法被你的数据证实——这不是说它无效,而是说你证明不了。
- 最小可检测差异 ≈ 噪声底线 × 2(因为两组数据相减,噪声叠加)。
- 噪声底线有三个用途:判断优化可信度、设定 CI 门禁阈值(×1.5–2)、判断环境是否可用。
- 警惕趋势漂移(10 轮单调上升)——那不是噪声,是环境在变,必须先解决。
- 门禁设计原则:宁可漏报,不可误报。
八、自测
- 你的环境噪声底线是 ±8%(P99)。一个优化声称把 P99 从 210 ms 降到 190 ms(-9.5%)。你该怎么表述这个结论?
- 你在测噪声底线时发现 10 轮的 P99 从 93 ms 单调上升到 100 ms。这说明什么?你会怎么处理?
- 为什么 CI 门禁的阈值要设成「噪声底线 × 1.5–2」,而不是直接等于噪声底线?
- 正确的表述:「观测到 P99 从 210 ms 变化到 190 ms(-9.5%),略高于本环境 8% 的噪声底线,但小于最小可检测差异(约 16%)。因此这个改进方向是可信的,但幅度需要在更干净的环境中验证。」 关键点:① 不要直接说「提升 9.5%」——那是把噪声当成果;② 也不要全盘否定——9.5% > 8%,有一定证据;③ 建议的下一步:增加轮数(比如 10 轮)、或用更精确的指标(比如对比 P50 或 QPS,它们的噪声可能更小)、或在更干净的环境重测;④ 如果这个优化成本很低(比如改一行配置),可以先采纳并继续观察;如果成本高(引入新组件),应该先验证幅度。
- 这说明环境在漂移,不是噪声。噪声的特征是「随机波动、无明显趋势」,而单调上升说明有系统性因素在累积。可能原因与处理:① 数据量增长(压测写了数据)——处理:检查表行数,给写操作加数据隔离或清理;② 缓存逐渐被污染/驱逐——处理:看缓存命中率趋势;③ 内存泄漏——处理:看堆基线趋势(第 3 章 3.5 的浸泡分析方法);④ 机器降频/发热——处理:检查 CPU 频率;⑤ 其他服务开始占用资源——处理:看系统负载与
st。处理原则:有漂移的环境测出的噪声底线不可信,必须先消除漂移,再重测。 - 因为阈值等于噪声底线会导致约 50% 的误报率——噪声是随机波动,正好跨过阈值的概率很高。具体来说:如果噪声在 ±8% 内均匀波动,那么「优化后的值」有相当大概率落在基线 −8% 之外(看起来"改善"了),也有相当大概率落在 +8% 之外(看起来"恶化"了)。乘 1.5–2 的含义:把阈值设在噪声的 1.5–2 倍处,只有超出正常波动范围的变化才触发告警——这样误报率会降到可接受水平(通常 < 5%)。代价是漏报:一个 10% 的真实退化如果没超过 12% 的阈值,就不会告警。但这个取舍是必要的——门禁如果天天误报,工程师就会忽略它,门禁实际上失效,比没有门禁更糟(因为它给人虚假的安全感)。