2. 数据血缘核心概念:数据源、数据节点、数据流、转换逻辑、依赖关系
好,咱们正式开始聊血缘分析的核心概念。说实话,我见过不少团队一上来就搞血缘工具,结果连这几个基本概念都没对齐,最后产出的血缘图谁也看不懂。所以这一章,咱们把地基打牢。
数据血缘,说白了就是回答三个问题:数据从哪来?中间经历了什么?最终去了哪? 而支撑这三个问题的,就是五个核心概念:数据源、数据节点、数据流、转换逻辑、依赖关系。
一句话总结:数据源是起点,数据节点是落脚点,数据流是路径,转换逻辑是规则,依赖关系是顺序。缺一个,血缘图就不完整。
2.1 数据源(Data Source)
数据源,就是数据的出生地。它可以是数据库、日志文件、消息队列、API 接口,甚至是另一个系统的输出。我个人习惯把数据源分为两类:原始数据源和中间数据源。
- 原始数据源:业务系统直接产生的数据,比如 MySQL 订单表、Kafka 点击流、Nginx 访问日志。这些数据一旦产生,基本不会在源头被修改。
- 中间数据源:经过加工后落地的数据,比如 Hive 中的清洗表、ClickHouse 中的聚合表。它们虽然是“源”,但本身也有上游。
我在项目中遇到过一个问题:某团队把 Kafka 的 topic 当作最终数据源,结果血缘图里所有数据都指向这个 topic。但实际这个 topic 的数据是从另一个数据库 CDC 同步过来的。你看,数据源没找对,整个血缘分析就偏了。
我的建议:在构建血缘时,尽量追溯到“不可再分”的原始数据源。比如数据库的 binlog、业务系统的埋点日志。这样溯源才能追到根。
2.2 数据节点(Data Node)
数据节点,是数据在流转过程中停留的地方。每个节点代表一个数据实体,比如一张表、一个文件、一个 topic、一个 API 的返回结果。
节点之间通过数据流连接,形成一张网。嗯,这里要注意:节点不是随便定义的。我见过有人把 SQL 中的每个临时表都算作一个节点,结果血缘图密密麻麻,根本没法看。
我个人习惯按存储边界来划分节点:
| 节点类型 | 典型例子 | 说明 |
|---|---|---|
| 持久化节点 | MySQL 表、HDFS 文件、Hive 表 | 数据会长期存储,可被多次读取 |
| 消息节点 | Kafka Topic、RocketMQ Queue | 数据流经但不长期驻留,消费后可能删除 |
| 临时节点 | Spark 临时视图、Flink 算子状态 | 仅存在于计算过程中,一般不纳入血缘图 |
你想想看,如果连临时节点都画进去,那血缘图就变成了执行计划图,反而失去了“溯源”的意义。
2.3 数据流(Data Flow)
数据流,描述的是数据从一个节点到另一个节点的移动过程。它是有方向的,通常用箭头表示。
数据流可以很简单,比如一条 INSERT INTO SELECT 语句;也可以很复杂,比如一个跨集群的数据同步任务。我记得有一次排查数据延迟问题,发现数据流中有一个 Kafka MirrorMaker 环节,带宽被打满了。如果没有数据流图,根本想不到瓶颈在这里。
在血缘分析中,数据流通常包含以下信息:
- 流向:从哪个节点到哪个节点
- 载体:通过什么工具或任务传输(如 DataX、Sqoop、Flink)
- 频率:实时流还是批处理,T+1 还是分钟级
- 量级:每次传输的数据量,用于评估影响范围
避坑指南:我曾经遇到一个案例,数据流图上只画了“表A → 表B”,但实际中间经过了三个微服务接口。这种“跳点”画法会导致溯源时漏掉关键环节。数据流必须完整,不能跳步。
2.4 转换逻辑(Transformation Logic)
转换逻辑,是数据在节点之间发生了什么变化。这是血缘分析中最有技术含量的部分。
转换逻辑包括但不限于:
- 字段映射:源表的 A 字段变成了目标表的 B 字段
- 数据清洗:去重、空值填充、格式转换
- 聚合计算:SUM、COUNT、AVG 等
- 业务规则:比如“订单金额超过 1000 元标记为高价值用户”
我建议在记录转换逻辑时,尽量细化到字段级别。表级别的血缘只能告诉你“数据从哪来”,字段级别的血缘才能告诉你“数据是怎么算出来的”。
举个例子:
-- 原始数据源:ods_orders
-- 目标节点:dws_daily_sales
INSERT INTO dws_daily_sales (date, total_amount, order_count)
SELECT
DATE(create_time) AS date,
SUM(amount) AS total_amount, -- 聚合转换
COUNT(DISTINCT order_id) AS order_count -- 去重计数
FROM ods_orders
WHERE status = 'paid' -- 过滤转换
GROUP BY DATE(create_time);
这段 SQL 里,每个字段的转换逻辑都清清楚楚。如果哪天报表数据对不上,顺着这个逻辑就能定位到是过滤条件变了,还是聚合函数写错了。
2.5 依赖关系(Dependency)
依赖关系,描述的是任务或节点之间的执行顺序。简单说就是:谁先跑,谁后跑,谁必须等谁。
依赖关系有两种常见形式:
- 数据依赖:表 B 依赖表 A 的数据,表 A 必须先产出数据。
- 任务依赖:任务 B 依赖任务 A 的执行结果,任务 A 必须先成功。
在实际项目中,我经常看到依赖关系混乱导致的数据问题。比如某个报表任务依赖的上游任务还没跑完,报表就提前调度了,结果数据是空的。这就是依赖关系没定义清楚。
我的经验:依赖关系最好用 DAG(有向无环图)来管理。每个节点只依赖它直接上游的节点,不要跨层依赖。我曾经接手过一个系统,任务 C 直接依赖任务 A,但任务 A 和任务 C 之间隔了两层,结果每次任务 A 一改,任务 C 就崩,排查起来非常痛苦。
2.6 五个概念的关系
这五个概念不是孤立的。它们组合起来,才构成完整的血缘视图。下面这张图可以帮你理清它们的关系:
2.7 小结
这一章我们拆解了数据血缘的五个核心概念。说白了,它们就是血缘分析的基本词汇。你只有掌握了这些词汇,才能读懂血缘图,才能用它来溯源问题。
我个人觉得,这五个概念中最容易被忽视的是转换逻辑。很多人只关注数据从哪来到哪去,却忽略了中间的计算过程。但恰恰是转换逻辑,决定了数据的业务含义。没有它,血缘分析就变成了“数据搬家记录”,而不是“数据价值追溯”。