第25章 数据治理与元数据管理:数据血缘、数据目录、数据质量监控、元数据采集
说实话,很多做ETL的兄弟干了三五年,还在纠结怎么写SQL、怎么调优。
但真正拉开差距的,是数据治理和元数据管理。
我见过太多团队,数据量上来了,表几百张、任务上千个,结果没人说得清某个字段从哪来的、谁在用、质量怎么样。这就是典型的「数据沼泽」——数据越多,越混乱。
这一章,我就把数据治理里最核心的四个东西掰开揉碎讲清楚:数据血缘、数据目录、数据质量监控、元数据采集。这些都是我这些年踩坑踩出来的经验。
25.1 元数据采集:一切治理的基础
元数据是什么?说白了就是「数据的数据」。比如一张表的名字、字段类型、分区信息、创建时间、更新频率——这些都是元数据。
没有元数据,后面的血缘、目录、质量监控全是空中楼阁。
25.1.1 采集哪些元数据?
我个人习惯把元数据分成三类:
| 类别 | 内容 | 来源 |
|---|---|---|
| 技术元数据 | 表结构、字段类型、分区信息、存储路径、文件格式 | Hive Metastore、MySQL information_schema、HDFS |
| 业务元数据 | 字段的业务含义、指标定义、数据域、数据标准 | 业务文档、数据字典、人工录入 |
| 操作元数据 | ETL任务执行记录、调度时间、数据量、错误日志 | 调度系统(如Airflow)、日志系统 |
我在项目中遇到过最典型的问题:技术元数据采集得很全,但业务元数据一片空白。结果就是,分析师看着字段名猜含义,猜错了就出报表,报表错了就甩锅给ETL。嗯,这锅我背过。
25.1.2 采集方式
元数据采集有两种主流方式:
- 拉模式(Pull): 定时从数据源拉取元数据。比如每天凌晨跑一个脚本,从Hive Metastore拉取所有表的元数据。优点是简单,缺点是实时性差。
- 推模式(Push): 数据源主动推送元数据变更。比如表结构变更时,通过Hook或事件通知推送到元数据中心。优点是实时,缺点是改造成本高。
我建议的做法是:拉模式兜底,推模式做增量。每天全量拉一次,同时监听关键变更事件做实时推送。这样既保证完整,又兼顾时效。
# 伪代码:从Hive Metastore拉取表元数据
def pull_table_metadata(database):
tables = hive_client.get_tables(database)
for table in tables:
metadata = {
'table_name': table.name,
'columns': table.columns,
'partition_keys': table.partition_keys,
'create_time': table.create_time,
'last_access_time': table.last_access_time,
'table_type': table.table_type # MANAGED_TABLE or EXTERNAL_TABLE
}
save_to_metadata_center(metadata)
25.2 数据血缘:追根溯源的能力
数据血缘,就是数据从哪来、经过哪些处理、最终到哪去的完整链路。
你想想看,一张报表上的「销售额」字段,它到底是从订单表直接来的,还是经过了好几层聚合?中间有没有被过滤?有没有被四舍五入?
没有血缘,你只能靠猜。猜错了,就是事故。
25.2.1 血缘的粒度
血缘可以分三个粒度:
- 表级血缘: 表A → 表B → 表C。知道数据在表之间怎么流转。
- 字段级血缘: 表A.col1 → 表B.col2。精确到字段级别。
- 任务级血缘: 哪个ETL任务产生了这张表,依赖哪些上游任务。
我个人认为,字段级血缘才是真正有价值的。表级血缘只能告诉你「有关系」,但说不清「什么关系」。我曾经排查过一个数据异常,表级血缘显示数据来自三张表,但字段级血缘一查,发现某个字段其实来自第四张表——因为SQL里有个子查询。嗯,这种坑我踩过不止一次。
25.2.2 血缘的构建方式
构建血缘主要有两种方法:
- 解析SQL: 解析ETL任务中的SQL语句,提取输入表和输出表、字段映射关系。这是最常用的方式。
- 运行时追踪: 在ETL框架层面埋点,记录数据读取和写入的详细信息。精度更高,但性能开销大。
我建议优先用SQL解析,成本低、覆盖广。对于关键链路,可以辅以运行时追踪做校验。
# 伪代码:解析SQL获取字段级血缘
def parse_lineage(sql):
# 使用SQL解析器(如sqlparse、antlr)解析SQL
parsed = sql_parser.parse(sql)
# 提取SELECT中的字段及其来源
output_fields = []
for select_item in parsed.select_items:
if isinstance(select_item, ColumnRef):
output_fields.append({
'output_field': select_item.alias or select_item.name,
'source_table': select_item.table,
'source_field': select_item.name
})
elif isinstance(select_item, FunctionCall):
# 处理聚合函数、表达式等
output_fields.append({
'output_field': select_item.alias,
'source_fields': extract_source_from_function(select_item)
})
return output_fields
25.3 数据目录:让数据可发现、可理解
数据目录,说白了就是「数据界的黄页」。
你公司有几千张表,分析师想找「用户活跃度」相关的数据,怎么找?挨个问?翻文档?
数据目录就是解决这个问题的。它把元数据组织成可搜索、可浏览的目录,让用户能快速找到想要的数据。
25.3.1 数据目录的核心功能
| 功能 | 说明 | 价值 |
|---|---|---|
| 搜索 | 支持按表名、字段名、业务标签、描述等关键词搜索 | 快速定位数据 |
| 浏览 | 按数据域、业务线、主题等维度组织目录树 | 发现相关数据 |
| 详情展示 | 展示表的元数据、字段定义、样例数据、血缘关系 | 理解数据含义 |
| 标签与评级 | 用户可以为数据打标签、评分、评论 | 社区化运营 |
| 数据预览 | 直接查看前N条数据样例 | 快速验证数据 |
我在项目中遇到过:数据目录上线了,但没人用。为什么?因为元数据不全、描述不准确、搜索体验差。后来我们强制要求每个表必须有业务描述和字段注释,才慢慢用起来。
25.4 数据质量监控:守住数据的底线
数据质量,是数据治理的终极目标。
你ETL做得再快、血缘画得再漂亮,数据是错的,一切归零。
我见过最惨的一次:某公司大促期间,报表上的GMV比实际少了30%,原因是上游一个字段类型从int变成了string,ETL没做校验直接入库了。嗯,那个月的数据团队绩效全挂。
25.4.1 数据质量的六个维度
业界公认的数据质量维度有六个:
- 完整性: 数据是否有缺失?比如用户表的手机号字段,空值率是多少?
- 准确性: 数据是否真实?比如订单金额是否在合理范围内?
- 一致性: 不同系统间的数据是否一致?比如CRM和BI的客户数是否对得上?
- 及时性: 数据是否在预期时间内到达?比如日报是否在早上9点前产出?
- 唯一性: 是否有重复数据?比如同一个用户ID出现多次?
- 有效性: 数据是否符合业务规则?比如年龄字段不能是负数?
25.4.2 质量监控的落地方式
我习惯的做法是:先做核心表,再做全量;先做规则,再做自动化。
- 定义规则: 和业务方一起,为每张核心表定义质量规则。比如「订单金额 > 0」、「用户ID不能为空」、「日增量在历史均值的±30%以内」。
- 配置监控: 将规则配置到质量监控平台,定时执行校验。
- 告警与处理: 校验失败时,通过邮件、钉钉、短信等方式告警,并记录到问题追踪系统。
- 持续优化: 根据告警情况,不断调整规则阈值和覆盖范围。
# 伪代码:数据质量校验规则示例
quality_rules = [
{
'table': 'ods_order',
'field': 'order_amount',
'rule': 'value > 0',
'severity': 'critical', # critical, warning, info
'action': 'block' # block: 阻断下游, alert: 仅告警
},
{
'table': 'ods_user',
'field': 'phone',
'rule': 'null_rate < 0.05', # 空值率不超过5%
'severity': 'warning',
'action': 'alert'
},
{
'table': 'dws_daily_sales',
'field': 'gmv',
'rule': 'abs(change_rate) < 0.3', # 日环比变化不超过30%
'severity': 'warning',
'action': 'alert'
}
]
def run_quality_check(rules):
for rule in rules:
result = execute_rule(rule)
if not result.passed:
if rule['action'] == 'block':
block_downstream_tasks(rule['table'])
send_alert(rule, result)
25.5 知识体系总览
下面这张图,是我对数据治理与元数据管理核心内容的总结。你可以把它当作一张「地图」,随时回来对照。
这张图里,元数据采集是基础,数据血缘和数据目录是应用,数据质量监控是保障。四者缺一不可。
好了,这一章的内容就到这里。数据治理和元数据管理,说白了就是让数据「看得清、找得到、信得过」。做到这三点,你的数据团队就能从「搬砖工」变成「数据管家」。
公众号:蓝海数据掘金营,微信deep3321