Spark 聚合式质量校验
不引入额外框架时,用一个 Spark SQL 聚合作业就能一次扫描产出多项质量指标:总行数、主键空值数、负值数、重复数、以及关键字段的均值与最大最小值。结果写入稽核表后,按天与基线对比(同比或分位数区间),比单一绝对阈值更早发现异常。这种做法的优点是零依赖、易接入现有调度;缺点是规则写在 SQL 里,增减规则要改代码重新发布,规则规模大时建议升级到配置化方案。
基本信息
| 实现方式 | 一条 Spark SQL 聚合作业一次扫描产出多指标 |
|---|---|
| 产出指标 | 行数、空值数、负值数、重复数、均值与分位数 |
| 结果去向 | 写入稽核表,供看板与环比基线对比 |
| 调度位置 | 产出任务之后,作为该表的质量关卡 |
| 扩展方向 | 规则增多后迁移到配置化规则引擎 |
典型使用场景
- ODS 入仓后立刻校验源端数据是否完整(行数与空值)
- DWD 产出后校验主键唯一与金额非负
- 数据量小的表直接全量校验,避免抽样遗漏长尾错误
- 结果写入稽核表后接看板,值班按表查看当天是否通过
- 临时排查:怀疑某表有问题时手工跑一次聚合作业
一次扫描算多指标
一次扫描算多指标
SELECT
COUNT(*) AS cnt, -- 总行数
SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) AS null_pk, -- 主键空值
SUM(CASE WHEN amount < 0 THEN 1 ELSE 0 END) AS neg_amount, -- 负金额
COUNT(*) - COUNT(DISTINCT order_id) AS dup_pk, -- 重复主键(近似)
ROUND(AVG(amount), 2) AS avg_amount, -- 均值
MAX(amount) AS max_amount
FROM ods_orders
WHERE dt = '2026-10-11';
-- 说明一:先做分区裁剪,避免全表扫描
-- 说明二:COUNT(DISTINCT) 在大表上开销较高,可用 group by 聚合替代
-- 说明三:结果写入稽核表后与基线对比,不要只看单值指标与判据
| 指标 | 正常值 | 异常含义 | 处置建议 |
|---|---|---|---|
| cnt 总行数 | 与基线同量级 | 骤降或翻倍 | 先查上游产出与过滤条件 |
| null_pk | 0 | 主键缺失 | 阻断下游并回溯上游 |
| neg_amount | 0 | 出现负金额 | 确认是否为退款场景 |
| dup_pk | 0 | 主键重复 | 按粒度声明核对并修复 |
| avg_amount | 在基线区间内 | 均值明显偏移 | 结合业务日历判断 |
COUNT(DISTINCT) 在大表上开销较高:先做分区裁剪,必要时改为 group by 后再聚合统计,避免校验本身成为瓶颈。
校验 SQL 与业务口径不一致(把测试单、冲正单算进去)时,指标天然偏差,稽核结果会被业务方质疑,规则很快失去权威性。
指标要留存历史:没有历史值时无法判断今天是真异常还是正常波动,第一天告警往往就没人信。