Skip to content

波动基线怎么定 ​

难度与前置

难度:进阶
前置:做过行数/金额监控;知道误报太多告警会被忽略。
读完能做什么:为指标选定基线算法与窗口,设置阈值与静默期,区分「真异常」与「季节性」,并用回测降低误报。

适用场景 ​

  • 行数、GMV、UV、空置率日波动告警噪声大
  • 大促 / 周末 / 月末天然起伏,固定 ±5% 不适用
  • 质量闭环里「异常检测」缺少统一基线方法(见 质量闭环)

不适用:

  • 强规则(主键唯一、枚举合法)——用确定性校验,不靠基线
  • 无历史数据的新表(先积累再基线,期间用人肉阈值)
  • 需要因果解释的根因分析(基线只负责「偏了」,根因另查)

真实场景(一条) ​

ADS 订单行数告警:相对昨日 ±10%。周末误报;大促漏报(涨了 80% 被当成异常关掉阈值后,真事故又漏)。改为:工作日用「同比上周同星期几」中位数 + MAD;大促日历切「活动基线」;空置率用绝对阈值。回测 90 天:误报降 70%,大促期间真延迟事故仍能打出。

怎么做(步骤清单) ​

1. 先定监控对象与粒度 ​

对象粒度备注
分区行数表 × 分区日最常用
业务指标金额 / UV与 口径 一致
质量率空置率、延迟率常用绝对阈值
链路延迟分位延迟见 新鲜度 SLA

同一对象不要混用「相对昨日」与「相对上周」而不标注。

2. 基线算法选型 ​

算法适用不宜
环比昨日极稳的系统指标周末/节假日
同比上周同星期几有周季节性长假、大促
近 N 天均值 ± kσ近似正态、无突变重尾、频繁活动
中位数 + MAD有毛刺、更稳健需解释给业务时稍抽象
分位数带(P50~P90 带)延迟类行数类需谨慎
日历切换基线大促 / 假期要维护日历表
text
默认推荐:
- 流量/订单行数:同比「上周同星期几」± 相对阈值,或 median+MAD
- 空置率/失败率:绝对阈值(如 > 1%)
- 延迟:SLA 绝对线 + 分位趋势

3. 用 SQL 沉淀基线表 ​

sql
-- 示意:日行数事实
CREATE TABLE IF NOT EXISTS dq_metric_daily (
  metric_name STRING,
  metric_date STRING,
  metric_value DOUBLE,
  tags MAP<STRING,STRING>
);

-- 计算「上周同星期几」基线与偏差
WITH today AS (
  SELECT metric_value AS v
  FROM dq_metric_daily
  WHERE metric_name = 'ads_order_rows'
    AND metric_date = '${biz_date}'
),
base AS (
  SELECT metric_value AS b
  FROM dq_metric_daily
  WHERE metric_name = 'ads_order_rows'
    AND metric_date = date_sub('${biz_date}', 7)
)
SELECT
  t.v,
  b.b,
  (t.v - b.b) / NULLIF(b.b, 0) AS rel_diff
FROM today t CROSS JOIN base b;
sql
-- 中位数 + MAD(近 28 个「同星期几」)
WITH hist AS (
  SELECT metric_value AS v
  FROM dq_metric_daily
  WHERE metric_name = 'ads_order_rows'
    AND date_format(metric_date, 'u') = date_format('${biz_date}', 'u')
    AND metric_date BETWEEN date_sub('${biz_date}', 196) AND date_sub('${biz_date}', 7)
),
stats AS (
  SELECT
    percentile_approx(v, 0.5) AS med,
    percentile_approx(abs(v - percentile_approx(v, 0.5)), 0.5) AS mad
  FROM hist
)
SELECT * FROM stats;
-- 告警示意:abs(v - med) > 3 * 1.4826 * mad

4. 阈值与日历 ​

  1. 相对阈值:如 |rel_diff| > 0.15 警告,> 0.30 严重(按系列调)
  2. 绝对地板:行数 < 1000 直接严重(防基线为 0)
  3. 日历表:is_promo/is_holiday 切换阈值或基线源
  4. 静默期:表延迟未到 SLA 前不比行数(与新鲜度联动)
sql
-- 日历示意
SELECT
  cal.day,
  cal.is_promo,
  CASE WHEN cal.is_promo THEN 0.50 ELSE 0.15 END AS warn_rel_th
FROM dim_calendar cal
WHERE cal.day = '${biz_date}';

5. 回测降误报(上线前必做) ​

  1. 取历史 60~90 天指标序列
  2. 用拟定规则「假跑」告警
  3. 统计:告警天数、与已知事故交集(召回)、无事故告警(误报)
  4. 调阈值 / 换算法直到误报可接受(如每周 < 2 次可解释)
bash
# 回测输出示意
echo "metric,method,days,alerts,known_incidents_hit,false_alerts"
# ads_order_rows,dow_wow_15pct,90,18,2,14
# ads_order_rows,median_mad_3,90,6,2,2

6. 告警内容要可行动 ​

告警消息至少含:

  • 指标名、分区、当前值、基线值、偏差
  • 基线方法(「上周同天」还是 MAD)
  • 相关表 / 任务链接
  • 建议第一步(查上游完成否 / 对账 / 联系值班)

避免只发「异常」两字。闭环见 质量闭环、对账。

7. 多指标联合(降噪) ​

组合解释
行数↓ + 上游未完成延迟,非质量坏
行数正常 + 金额↓口径/过滤事故嫌疑
空置率↑ + 行数不变解析/Join 丢字段

联合条件可减少「单一波动」误报。

8. 落地清单 ​

  1. 指标字典:名字、SQL、口径负责人
  2. 基线方法与参数入库
  3. 日历与静默规则
  4. 回测报告附 PR
  5. 告警路由与认领
  6. 季度复盘阈值

常见坑(至少牢记这些) ​

  1. 全局 ±5% 一把梭
    周末与大促要么吵死要么聋。

  2. 用含事故日的数据当基线
    基线被污染,真异常被「洗」成正常。

  3. 基线用均值但对重尾指标
    一次尖刺抬高均值,后续漏报。

  4. 表还没跑完就比行数
    新鲜度问题被当成丢数;先看 新鲜度 SLA。

  5. 告警无基线方法说明
    值班不知道该信「同比」还是「环比」,重复拉人。

  6. 只上告警不做回测
    第一周风暴,之后全员屏蔽告警。

如何验收(可量化) ​

  • [ ] 每条核心指标有文档化基线方法与参数
  • [ ] 90 天回测:误报与召回达到约定
  • [ ] 大促/假期日历切换演练通过
  • [ ] 告警文案含当前值/基线/方法
  • [ ] 与已知事故库对照:应鸣尽鸣
  • [ ] 静默期与上游 SLA 对齐
sql
-- 当日是否告警(落地结果表)
SELECT metric_name, metric_date, v, baseline, rel_diff, is_alert, method
FROM dq_alert_result
WHERE metric_date = '${biz_date}'
ORDER BY is_alert DESC, abs(rel_diff) DESC;
bash
echo "week,false_alert_count,incident_recall"
# 2026-W38,2,1.0

相关面试题 ​

占位:与题库小程序对齐后补链接(建议关联:数据质量告警、异常检测基线、对账、新鲜度 SLA)。


改写说明:结构与判断标准参考 Wood 原创数仓/面试文,已改写成可执行清单;未包含未公开公司数据与内部表名。