外观
波动基线怎么定
难度与前置
难度:进阶
前置:做过行数/金额监控;知道误报太多告警会被忽略。
读完能做什么:为指标选定基线算法与窗口,设置阈值与静默期,区分「真异常」与「季节性」,并用回测降低误报。
适用场景
- 行数、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 * mad4. 阈值与日历
- 相对阈值:如
|rel_diff| > 0.15警告,> 0.30严重(按系列调) - 绝对地板:行数
< 1000直接严重(防基线为 0) - 日历表:
is_promo/is_holiday切换阈值或基线源 - 静默期:表延迟未到 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. 回测降误报(上线前必做)
- 取历史 60~90 天指标序列
- 用拟定规则「假跑」告警
- 统计:告警天数、与已知事故交集(召回)、无事故告警(误报)
- 调阈值 / 换算法直到误报可接受(如每周 < 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,26. 告警内容要可行动
告警消息至少含:
- 指标名、分区、当前值、基线值、偏差
- 基线方法(「上周同天」还是 MAD)
- 相关表 / 任务链接
- 建议第一步(查上游完成否 / 对账 / 联系值班)
7. 多指标联合(降噪)
| 组合 | 解释 |
|---|---|
| 行数↓ + 上游未完成 | 延迟,非质量坏 |
| 行数正常 + 金额↓ | 口径/过滤事故嫌疑 |
| 空置率↑ + 行数不变 | 解析/Join 丢字段 |
联合条件可减少「单一波动」误报。
8. 落地清单
- 指标字典:名字、SQL、口径负责人
- 基线方法与参数入库
- 日历与静默规则
- 回测报告附 PR
- 告警路由与认领
- 季度复盘阈值
常见坑(至少牢记这些)
全局 ±5% 一把梭
周末与大促要么吵死要么聋。用含事故日的数据当基线
基线被污染,真异常被「洗」成正常。基线用均值但对重尾指标
一次尖刺抬高均值,后续漏报。表还没跑完就比行数
新鲜度问题被当成丢数;先看 新鲜度 SLA。告警无基线方法说明
值班不知道该信「同比」还是「环比」,重复拉人。只上告警不做回测
第一周风暴,之后全员屏蔽告警。
如何验收(可量化)
- [ ] 每条核心指标有文档化基线方法与参数
- [ ] 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 原创数仓/面试文,已改写成可执行清单;未包含未公开公司数据与内部表名。