容量报表连续三个月每月涨两成,按这个斜率排下去,第三个月底就该扩容。团队提前扩了一轮,第四个月流量不涨反跌,资源白买。更常见的是反向版本:连涨三期被判断为"业务在增长",于是所有容量问题都归因于增长,直到系统在没有增长的时段崩掉。
连涨三期是非常弱的信号:它能排除的比能得出的多——能排除"完全随机的白噪声",不能得出"增长会延续""原因是什么""什么时候停"。
1. 三期上升能得出什么
| 问题 | 三期上升能否回答 | 原因 |
|---|---|---|
| 是否完全随机波动 | 能(排除最弱假设) | 纯噪声连涨三次概率不高 |
| 是否有趋势 | 不能 | 三次点不足以区分趋势与周期 |
| 增长会延续多久 | 不能 | 外推依赖机制假设,数据不提供 |
| 是什么驱动的 | 不能 | 同样三个点可由多种机制产生 |
| 该不该现在扩容 | 不能 | 取决于阈值与提前期,而非斜率 |
同一组三个点,至少有四种机制能生成:
① 真实趋势:每天稳步增加,机制稳定
② 周期上行段:季度/活动周期中的上升半周期,之后必然回落
③ 水平跃迁:某次发版或渠道投放导致一次性台阶,之后走平
④ 口径变更:采集范围扩大(新增端、新增埋点)造成的台阶
─── 三期内它们完全同形,四期后开始分岔;区分靠机制信息,不靠拟合
所以"连涨三期"的正确用法是触发进一步调查,而不是直接支撑结论。把它当成待验证线索,成本很低;把它当成结论,代价在第四个月显现。
组织层面的原因更硬:趋势图一进周会就被当成"已确认的事实",之后没人再回头质疑。一个数在决策链上每被引用一次,质疑它的成本就升一档——所以趋势判断的关键动作发生在它第一次进会议之前。
2. 趋势误读的四个来源
| 来源 | 机制 | 典型表现 | 识别方法 |
|---|---|---|---|
| 样本太少 | 点太少,噪声被读成信号 | 连涨三期、单点跳变 | 拉长窗口看同一结论是否成立 |
| 周期未分开 | 趋势里混了周期分量 | 每季度末都"增长" | 同比而非环比 |
| 口径变了 | 采集/统计范围变化产生台阶 | 某日整段抬高 | 查口径断点表 |
| 单一事件驱动 | 一次性事件被当成持续增长 | 大促、发版、渠道投放后不回落 | 剔除事件窗后重看斜率 |
其中两个来源最容易被合并误判:大促既是周期又是事件。只看同比,会把"今年大促力度更大"读成"整体增长更快"。
-- 环比:容易把周期当成趋势
SELECT date_trunc('month', ts) AS m, count(*) AS n
FROM event WHERE ts >= now() - interval '6 months' GROUP BY 1 ORDER BY 1;
-- 同比:扣掉年度周期后再看方向
SELECT date_trunc('month', ts) AS m,
count(*) AS n,
lag(count(*), 12) OVER (ORDER BY date_trunc('month', ts)) AS n_yoy
FROM event WHERE ts >= now() - interval '24 months' GROUP BY 1 ORDER BY 1;
判断规则:观察窗必须覆盖至少两个完整周期,否则同比无法计算,环比不可信。窗长小于一个周期的"趋势"不是趋势。
| 比较方法 | 适用前提 | 不适用时 |
|---|---|---|
| 环比(与上期比) | 周期效应弱、窗口对齐 | 存在周/月/季周期时必然误判 |
| 同比(与去年同期比) | 至少两个完整年度周期 | 业务模式一年内已大改 |
| 事件外剔除后再比 | 事件窗可识别且长度已知 | 事件持续蔓延、无法划界 |
| 分组对比(实验 vs 对照) | 有可比的对照组 | 无同期对照、全量生效的改动 |
三种方法都不满足时,唯一诚实的输出是"当前数据不足以判断方向"。
3. 斜率变化、水平变化与阈值型指标
"指标在涨"和"涨得更快了"是两件事,混用会让扩容提前期算错。
| 变化类型 | 数学含义 | 常见误读 | 应对 |
|---|---|---|---|
| 水平变化 | 一次性台阶 | 被当成"加速增长" | 找台阶来源(发版、口径、渠道) |
| 斜率变化 | 增长速率变化 | 被当成暂时波动 | 需要更长窗口确认,通常要 2 倍窗长 |
| 周期性波动 | 固定周期的上下 | 被当成趋势方向 | 同比或做季节分解 |
| 噪声 | 无结构随机 | 被当成拐点 | 看置信区间,不看单点 |
阈值型指标(SLO 达标率、任务成功率、通过率)没有斜率可言。它的取值被钉在上下界附近,趋势方向由分母波动决定,讨论"连续三期上升"在这里没有决策含义——有意义的只有"离阈值多远""超阈值的持续时长"。
扩容提前期不是从斜率算的,而是从阈值 − 当前值与已知的获取周期算的:
─── 触发线固定,先算剩余空间与到货时间的关系
CURRENT=0.62 ─── 当前水位
LIMIT=0.80 ─── 安全线
LEAD_TIME=21 ─── 天:采购/审批/测试的最短周期
─── 若 (LIMIT - CURRENT) / 获取周期 > 近期最坏增速,就不必提前动手
awk -v c=$CURRENT -v l=$LIMIT -v t=$LEAD_TIME 'BEGIN{ printf "剩余空间 %.2f, 安全增速上限 %.4f/天\n", l-c, (l-c)/t }'
// 阈值型指标:不要看斜率,看超限时长与消耗速度
slo:error_budget_burn_rate:1h = sum(rate(http_requests_total{code=~"5.."}[1h]))
/ sum(rate(http_requests_total[1h])) / (1 - 0.999)
// 报警条件:短窗高倍率 或 长窗低倍率,都不是"趋势上升"
burn:fast = slo:error_budget_burn_rate:1h > 14.4
burn:slow = slo:error_budget_burn_rate:6h > 6
4. 外推的假设与"看起来有拐点"
任何外推都默认了两件事:机制不变(生成数据的过程继续生效)与环境不变(没有新变量进入)。这两条几乎从不在数据里,只能靠人去确认。
| 外推假设 | 何时成立 | 何时必然失效 |
|---|---|---|
| 机制不变 | 稳定期的自然增长 | 渠道投放停止、活动结束 |
| 环境不变 | 无新版本、无新政策 | 发版、限流、竞品动作 |
| 结构不变 | 人群与端分布稳定 | 新端上线、用户结构变化 |
统计噪声与真实变化的区分,在小基数时尤其重要:
小基数噪声直觉(用于判断"这个涨幅是否值得看")
─── n 很小时,计数本身的相对波动约为 1/√n 量级
─── n ≈ 100 时,单期 ±10% 的波动很常见,连涨三期的概率不低
─── n ≥ 万级时,±5% 的变化才需要解释
─── 结论:谈趋势前先看基数,基数小就先看绝对量
"看起来有个拐点"是人的模式识别本能:给定一段折线,人几乎总能找到一段像拐点的区间。判定拐点的成本很高,所以顺序应该是先问机制(有没有可以产生拐点的事件),再看数据是否支持,而不是反过来。
可操作的替代:把"是否存在拐点"换成"三档情景下我是否都要行动"。三档都要动时,拐点判不判不影响决策;三档动作不同时,才值得为区分拐点投入成本。
情景分析替代单点外推:给区间,不给唯一数字
─── 延续:上期 × 1.20,机制不变
─── 走平:上期 × 1.00,一次性台阶后的水平
─── 回落:上期 × 0.75,周期下行段
─── 按三档分别算所需容量,用覆盖率最高的一档定提前期,不取中位数
5. 排错:五种趋势误判的现场
| 现象 | 最可能的来源 | 第一步动作 |
|---|---|---|
| 连涨三月后第四月下跌 | 周期未分开 | 做同比,确认是否周期性上行段 |
| 某日整段抬高后再不变 | 口径变更 | 查口径断点表,确认采集范围变化 |
| 大促后指标不回落 | 单一事件驱动 | 剔除事件窗后重算斜率 |
| 达标率"持续上升"却告警不断 | 阈值型指标被当趋势 | 改看预算消耗速率而非斜率 |
| 小基数指标月度大涨大跌 | 统计噪声 | 先看绝对量,再决定是否解释 |
6. 趋势判断的最低要求与边界
最低要求可以写成一个可执行的检查清单,任一不满足就不该给方向性结论:
─── 观察窗 ≥ 2 个完整周期(否则只能算同比,不能谈趋势)
─── 口径全程一致(不一致先对齐,不把台阶算进斜率)
─── 事件窗已标注(大促、发版、投放单独标记,不混入基线)
─── 基数量级已知(小基数只给绝对量与区间)
─── 结论形态是区间/情景,而不是一个外推数字
"等数据再多一点"与"现在就决策"的取舍取决于决策的可逆性与等待成本:可逆决策(提前买少量资源、加一个灰度开关)不必等,不可逆决策(长期合同、架构改造)应该等机制信息而不是等数据点。
决策可逆?
├─ 可逆 + 等待成本高(故障风险在积累) → 按最坏情景先动,保留回滚
├─ 可逆 + 等待成本低 → 等到能算出同比再动
├─ 不可逆 + 机制未知 → 先查机制(发版/渠道/口径)再决策
└─ 不可逆 + 机制已明确 → 直接做情景分析,不再等数据点
| 度量 | 含义 | 观测方式 |
|---|---|---|
| 观察窗长度 | 覆盖的完整周期数 | 数据范围 / 周期长度 |
| 口径一致性 | 窗口内是否发生口径变更 | 断点表条数 |
| 同比环比偏离 | 两种口径方向差异 | 同比与环比结论是否相反 |
| 预测命中率 | 外推值落在实际区间内的比例 | 历次预测与实际对比 |
| 边界场景 | 结论 |
|---|---|
| 低频指标(季度级) | 趋势判断让位于情景分析,点位太少 |
| 基数极小(百级以下) | 只谈绝对量与区间,不谈百分比趋势 |
| 机制即将变化(已知要改版/换渠道) | 历史斜率无效,直接做情景推演 |
| 指标已钉在上下界(阈值型) | 只谈超限时长与消耗速率 |
一句话判据:趋势是机制在数据上的投影;机制不清楚时,先查机制,再谈斜率。
自测
- 连续三期上升,能排除的假设是什么,不能回答的问题是什么?
- 同样的三个点可能来自哪几种机制,靠什么把机制区分开?
- 观察窗为什么要覆盖两个完整周期,只覆盖一个周期时该怎么办?
- 阈值型指标为什么不适合谈趋势,该改看什么?
- 外推的两个隐含假设是什么,各在什么情况下必然失效?
- 什么情况下"等更多数据"没有价值,应该直接转到情景分析?