4、数据质量规则引擎:让校验规则活起来
规则引擎,说白了就是把「什么时候该做什么检查」这件事,从代码里抽出来,变成可配置、可热更新的东西。我刚开始做数据质量时,规则都是硬编码在 Spark 作业里的——改一条规则就要重新打包上线,那叫一个痛苦。后来接触了规则引擎,才明白什么叫「把逻辑还给业务」。
4.1 规则引擎的核心概念
规则引擎不是什么新东西。它本质上是一个「条件-动作」的执行器。你给它一条规则,比如「如果 age 字段为 null,则标记为脏数据」,引擎就会在数据流过时自动触发这个检查。
我个人习惯把规则引擎拆成三个核心部件:
- 规则仓库:存规则的地方。可以是数据库、文件、甚至配置中心。
- 规则解析器:把人类可读的规则(比如 JSON、YAML、DSL)转成机器可执行的逻辑。
- 规则执行器:真正跑检查的地方。可以是单机线程池,也可以是分布式计算框架。
关键点:规则引擎的价值不在于「能跑规则」,而在于「规则和代码解耦」。你改规则时不需要重启服务,不需要改代码,甚至可以让业务人员自己配。
举个例子。我曾经在一个金融项目中,业务方每周都要调整风控规则。如果用硬编码,每次改规则都要走发布流程,至少两天。上了规则引擎后,他们直接在页面上拖拽配置,十分钟生效。嗯,这就是规则引擎的威力。
4.2 规则引擎的架构设计
规则引擎的架构,我一般画成三层:
你想想看,这个架构最妙的地方在哪?每一层都可以独立扩展。规则管理层可以接配置中心,解析层可以支持多种规则语法,执行层可以切换计算引擎。我在一个实时数仓项目里,就同时用了 Flink 和 Spark 两套执行器,上层规则完全不用改。
4.3 规则引擎的配置与部署
配置规则引擎,我建议从最简单的 JSON 格式开始。别一上来就搞复杂的 DSL,容易把自己绕进去。
下面是一个典型的规则配置示例:
{
"rule_id": "R001",
"rule_name": "非空校验-用户手机号",
"data_source": "ods.user_info",
"condition": {
"field": "phone",
"operator": "is_null",
"value": null
},
"action": {
"type": "reject",
"severity": "error",
"output": "dwd.dirty_data"
},
"schedule": {
"cron": "0 0/5 * * * ?",
"timeout_sec": 300
}
}
我的经验:规则配置里一定要加 timeout_sec。我曾经遇到过一条规则因为数据量暴增,跑了两个小时还没结束,把整个执行队列堵死了。从那以后,我每条规则都设超时。
部署方面,我推荐容器化。规则引擎本身是无状态的,可以水平扩展。你只需要把规则仓库挂载到共享存储上,多个引擎实例就能共享同一套规则。
| 部署方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 单机部署 | 开发测试、小规模 | 简单、运维成本低 | 无法水平扩展 |
| Kubernetes 集群 | 生产环境、弹性伸缩 | 高可用、自动扩缩 | 需要 K8s 运维能力 |
| 嵌入式计算引擎 | 实时流处理 | 低延迟、数据不落盘 | 与计算引擎耦合 |
4.4 规则引擎的调度与监控
规则配好了,部署上去了,接下来就是调度和监控。这块做不好,规则引擎就是个黑盒子——你根本不知道它跑没跑、跑得怎么样。
调度策略我一般分两种:
- 定时调度:用 Cron 表达式,适合离线批处理。比如每天凌晨跑一次全量数据校验。
- 事件驱动:数据流入时触发,适合实时场景。比如 Kafka 消息过来就执行规则。
监控方面,我重点关注三个指标:
- 规则执行成功率:低于 99% 就要报警。
- 规则执行延迟:超过超时时间要记录并重试。
- 规则命中率:命中率突然下降,可能是规则写错了,也可能是数据质量变好了——需要人工判断。
避坑指南:我曾经遇到过一条规则命中率从 5% 突然降到 0%,排查了半天,发现是上游改了字段名,规则里的字段名没同步更新。所以,规则监控一定要加上「字段变更检测」——当数据源的 schema 发生变化时,自动告警。
调度与监控的架构,我习惯用一张图来概括:
最后说一句。规则引擎不是银弹。如果你的数据质量规则只有三五条,硬编码反而更简单。但一旦规则超过 20 条,或者需要频繁变更,规则引擎的价值就体现出来了。我个人的判断标准是:当业务方开始频繁找你「改个规则」时,就该上规则引擎了。