4. 数据质量规则引擎设计:规则定义、规则分类、规则模板、规则调度

规则引擎这东西,说白了就是给数据质量装上一套「自动交警」。数据在流转,谁违规、谁超速、谁闯红灯,得有个东西盯着。我见过太多团队,一开始靠人工写脚本查数据,项目一多直接崩盘。嗯,今天我们就聊聊怎么把这套引擎搭起来。

4.1 规则定义:先搞清楚你要查什么

规则定义是地基。地基歪了,后面全白搭。我个人习惯把规则定义拆成三个要素:检查对象、检查逻辑、阈值/期望。

规则定义三要素

  • 检查对象:哪个表?哪个字段?哪个批次?
  • 检查逻辑:怎么查?是空值检测、值域校验,还是主键唯一性?
  • 阈值/期望:什么算合格?空值率 < 5%?还是必须等于 0?

举个例子。我在项目中遇到过一张订单表,业务方说「订单金额不能为负」。好,规则定义就是:表:ods_order,字段:amount,逻辑:amount >= 0,期望:100% 通过。就这么简单。但如果你连检查对象都没写清楚,后面调度起来就是一团乱麻。

小技巧:规则定义最好用 JSON 或 YAML 存,别写死在代码里。方便后面动态加载和版本管理。

4.2 规则分类:别让规则变成一锅粥

规则一多,不分类就是灾难。我曾经接手过一个项目,规则库里有 2000 多条规则,全混在一起。想查一条「用户手机号格式校验」的规则,得翻半小时。后来我按以下维度做了分类,效果立竿见影。

分类维度 子类 说明
按检查时机 离线规则 / 实时规则 离线跑批用,实时流处理用
按数据层级 字段级 / 记录级 / 表级 / 跨表级 粒度不同,检查逻辑差异很大
按质量维度 完整性 / 准确性 / 一致性 / 及时性 / 唯一性 经典 DQ 维度,方便对齐业务
按规则来源 系统内置 / 用户自定义 / 机器学习发现 内置规则开箱即用,自定义规则灵活

你想想看,有了这个分类,你在规则引擎里搜「实时+字段级+完整性」,唰一下就能定位到具体规则。效率翻倍。

4.3 规则模板:别重复造轮子

规则模板是我最想安利的东西。很多团队每条规则都手写 SQL,累不累?其实 80% 的规则都是套路。比如「空值检测」,换个表名、字段名就能复用。模板就是把这些套路固化下来。

我习惯把模板设计成「参数化 SQL + 元数据」的结构:

{
  "templateId": "T001",
  "name": "空值检测",
  "category": "完整性",
  "sqlTemplate": "SELECT COUNT(*) AS total, SUM(CASE WHEN ${field} IS NULL THEN 1 ELSE 0 END) AS null_count FROM ${table} WHERE ${partition}",
  "params": ["table", "field", "partition"],
  "expectation": "null_count / total < ${threshold}"
}

你看,只要传不同的 table、field、partition、threshold,就能生成一条新规则。我在项目中用这套模板,把 500 条规则缩减到 30 个模板,维护成本直线下降。

注意:模板里的 SQL 一定要做防注入处理。参数化传值,别直接拼接字符串。我曾经见过有人把表名拼进去,结果被注入了删库脚本……嗯,不说了。

4.4 规则调度:让规则按时跑起来

规则定义好了,分类清楚了,模板也建了,接下来就是调度。调度不是简单设个 cron 就完事。你得考虑依赖、优先级、重试、告警。

我一般把调度设计成三层:

  • 触发层:时间触发(每天凌晨 2 点)、事件触发(数据入库完成)、API 触发(手动调用)。
  • 执行层:规则引擎拿到待执行规则列表,按优先级排序,分发给执行器。执行器可以是 Spark、Flink、或者简单的 JDBC 连接。
  • 反馈层:执行完的结果写回结果表,失败的重试 3 次,超过阈值就发告警(钉钉、邮件、短信)。

下面这张图是我常用的规则调度流程,你可以参考一下:

数据质量规则调度流程图 数据质量规则调度流程图 触发层 时间触发 (Cron) 事件触发 (Kafka) API 触发 执行层 Spark 执行器 Flink 执行器 JDBC 执行器 反馈层 结果写入 DQ 结果表 失败重试 + 告警 说明:触发层接收调度信号,执行层分发规则到不同引擎,反馈层收集结果并处理异常

调度这块有个坑,我得提醒你:千万别把所有规则放在一个调度任务里。我曾经这么干过,结果一条慢 SQL 拖死了整个调度链路,后面的规则全超时。正确的做法是按优先级和资源消耗拆分,比如把「主键唯一性」这种轻量规则和「跨表一致性」这种重量规则分开调度。

避坑指南:调度频率别设太密。我见过有人每 5 分钟跑一次全量规则,结果数据没变,白白浪费资源。建议根据数据更新频率来设,比如 T+1 的数据每天跑一次就够了。

4.5 规则引擎的整体架构

最后,我把上面这些串起来,给你看一个完整的规则引擎架构。说白了就是四层:规则管理层(定义、分类、模板)、调度层(触发、排队、分发)、执行层(多引擎适配)、结果层(存储、告警、可视化)。

我个人习惯用一张表来总结各层的职责:

层级 核心组件 关键能力
规则管理层 规则库、模板库、分类器 增删改查、版本控制、参数化
调度层 调度器、任务队列、优先级管理器 定时/事件触发、依赖管理、限流
执行层 执行器适配器、连接池 多引擎支持、资源隔离、超时控制
结果层 结果存储、告警服务、看板 结果持久化、分级告警、趋势分析

嗯,这套架构我在好几个项目里验证过,从几百条规则到上万条规则都能撑住。核心就是「规则与执行解耦、调度与资源隔离」。你照着这个思路搭,基本不会出大问题。