首页/数据/数据工程与 ETL 速查/实时链路的数据质量校验

实时链路的数据质量校验

流式链路的校验在管道内完成:对每条记录做轻量检查(主键非空、金额非负、枚举合法),错误记录写入死信队列;重校验(跨表关联、全量比对)放到旁路批作业,避免拖慢实时链路。

实时链路的数据质量校验

流式链路的校验原则是“轻量留在线内、重型推到线外”:对每条记录做无状态检查(主键非空、金额非负、枚举合法、时间不越界),不通过的记录写入死信队列,主流程继续;跨表关联、历史全量比对这类重校验放到旁路批作业或下游质量任务里做,避免维表 join 与大范围聚合并入主链路造成反压。死信队列必须有消费方、告警与清理策略,否则它只是另一个没人看的垃圾桶。

基本信息

线内检查无状态轻量规则:非空、范围、枚举、正则
错误去向死信队列(DLQ)或隔离表,附带失败原因
线外检查跨表关联、全量比对、基线波动放到批作业
性能约束避免维表 join 与大规模聚合,防止反压
DLQ 要求有消费方、有告警、有清理与重放流程

典型使用场景

  • 订单实时入仓:拦截主键为空与金额为负的记录
  • 埋点数据接入:校验时间戳范围与必填字段,异常进 DLQ
  • 风控实时链路:枚举取值越界直接隔离,避免下游判断出错
  • 实时看板:线内只做轻量校验,波动类检查放到旁路批任务
  • 故障演练:人为注入脏数据,验证 DLQ 告警与重放流程是否有效

流内旁路(Flink SQL 思路)

流内旁路(Flink SQL 思路)
-- 合法数据进主表(轻量、无状态检查)
INSERT INTO orders_clean
SELECT * FROM orders_raw
WHERE order_id IS NOT NULL
  AND amount >= 0
  AND status IN ('PAID','REFUND','CLOSED');

-- 非法数据进死信表,附带失败原因便于分类处理
INSERT INTO orders_dlq
SELECT *, 'invalid' AS reason, CURRENT_TIMESTAMP AS dlq_time
FROM orders_raw
WHERE NOT (order_id IS NOT NULL AND amount >= 0);

-- 说明:跨表关联与历史比对不要放进这两个语句,交给旁路批作业

线内与线外分工

校验类型放置位置例子原因
无状态单条检查线内非空、范围、枚举开销小,可逐条执行
状态类检查线内有窗口聚合去重、乱序容忍需窗口,但要控制状态大小
跨表关联线外批作业与维表核对归属维表 join 易造成反压
历史比对线外批作业与昨日全量比对数据量与资源不适合流内
死信队列必须有消费方与告警:没有下游处理的 DLQ 只是另一个垃圾桶,错误率上升也不会有人知道。
在实时链路里做重校验(维表 join、全量比对)会产生反压拖慢整体吞吐,甚至让上游写入被阻塞,影响面远超校验收益。
DLQ 要有重放流程:修复规则或数据后能按时间范围重放,否则错误记录只能长期堆积或丢弃。

易错点

  • 实时链路做重校验(维表 join、全量比对),产生反压拖慢吞吐甚至阻塞上游
  • DLQ 无监控无处理,错误率上升无人知晓,问题在下游才暴露
  • 把 DLQ 当永久存储,不做清理与重放设计,存储持续膨胀
  • 线内规则过于宽松(只看非空),字段格式错误流入下游,后续清理成本更高

数据来源与参考

  • Apache Flink 官方文档(Flink SQL)
  • 行业流式数据质量实践
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌