4、数据源接入与元数据管理:如何对接Hive、Kafka、MySQL等数据源,构建统一的元数据中心

数据质量看板,说白了就是“数据的数据”在说话。你连源头的数据长什么样都不清楚,后面的质量规则、监控告警全是空中楼阁。

我刚开始做数据治理那会儿,接过一个项目。业务方说“我们数据都在Hive里”,结果一查,Hive表有三千多张,一半没有注释,字段命名全靠猜。更头疼的是,实时数据走Kafka,业务库还有MySQL分库分表。三个数据源,三种元数据格式,怎么统一?

嗯,这就是我们今天要聊的核心——数据源接入与元数据管理。

4.1 元数据中心:为什么你需要一个“数据的地图”

元数据是什么?就是描述数据的数据。表名、字段名、类型、分区、主键、更新时间、数据量……这些信息构成了你理解数据的基础。

没有元数据中心,你会遇到什么?

  • 开发问:“这个字段是啥意思?”——没人知道。
  • 运维问:“这张表数据量多大?”——得跑一遍count。
  • 分析师问:“数据从哪来的?”——查半天链路。

我个人习惯,在搭建数据质量看板之前,先搭元数据中心。哪怕初期只接入核心表,也比没有强。

核心原则:元数据中心是数据质量看板的“前置依赖”。没有元数据,质量规则无从绑定,血缘关系无法追溯。

4.2 数据源接入:三种典型场景的实战方案

我们团队对接过的主流数据源,无非三类:离线数仓(Hive)、实时消息(Kafka)、关系型数据库(MySQL)。每种接入方式都不一样,我一个个说。

4.2.1 对接Hive:元数据藏在Hive Metastore里

Hive的元数据,其实都存储在Metastore中。Metastore背后通常是MySQL或PostgreSQL。你直接连Metastore的库,就能拿到所有表结构信息。

我在项目中遇到过一个问题:Metastore里存的字段类型是Hive内部的字符串表示,比如array<string>、struct<id:int,name:string>。解析起来有点麻烦。我的做法是写一个轻量级的解析器,把复杂类型拆成扁平结构,方便后续存储和展示。

-- 示例:查询Hive Metastore获取表字段信息
SELECT 
    d.NAME AS database_name,
    t.TBL_NAME AS table_name,
    c.COLUMN_NAME,
    c.TYPE_NAME,
    c.INTEGER_IDX AS col_order,
    t.TBL_ID
FROM 
    TBLS t
    JOIN DBS d ON t.DB_ID = d.DB_ID
    JOIN COLUMNS_V2 c ON t.TBL_ID = c.CD_ID
WHERE 
    d.NAME = 'your_database'
    AND t.TBL_NAME = 'your_table'
ORDER BY 
    c.INTEGER_IDX;
小技巧:Hive表的分区信息存储在PARTITIONS和PARTITION_KEYS表中。如果你需要监控分区数据是否准时到达,记得把分区字段也拉入元数据中心。

4.2.2 对接Kafka:Schema Registry是你的好朋友

Kafka的数据是流式的,没有固定的“表结构”。但实际生产中,消息都有Schema。要么是Avro,要么是Protobuf,要么是JSON Schema。

我个人强烈建议使用Confluent Schema Registry。它统一管理Kafka消息的Schema,并且支持兼容性检查。你只需要调用它的REST API,就能拿到每个Topic的字段定义。

# 示例:通过Schema Registry API获取Topic的Schema
GET /subjects/{subject_name}/versions/latest

# 返回示例(Avro Schema)
{
  "subject": "user_click-value",
  "version": 3,
  "id": 101,
  "schema": "{\"type\":\"record\",\"name\":\"UserClick\",\"fields\":[{\"name\":\"user_id\",\"type\":\"string\"},{\"name\":\"click_time\",\"type\":\"long\"},{\"name\":\"page_id\",\"type\":\"int\"}]}"
}

我曾经踩过一个坑:某个Topic的Schema升级了,加了新字段,但下游消费者没更新。结果数据反序列化失败,整条链路断了。后来我在元数据中心里加了一个Schema版本变更记录表,每次变更都触发告警,通知相关方。

注意:Kafka Topic的元数据不仅包括Schema,还包括分区数、副本数、消息保留时间。这些信息对数据质量监控同样重要,比如“消息堆积”就需要知道分区数。

4.2.3 对接MySQL:直接查INFORMATION_SCHEMA

MySQL的元数据获取最简单。每个MySQL实例都有INFORMATION_SCHEMA库,里面存了所有表、字段、索引、约束的信息。

但要注意,INFORMATION_SCHEMA在表多的时候查询很慢。我遇到过一张库里有5000多张表,直接SELECT * FROM TABLES卡了十几秒。后来我改成按库名过滤,分批拉取。

-- 示例:获取指定数据库的所有表及字段信息
SELECT 
    t.TABLE_NAME,
    t.TABLE_ROWS,
    t.AUTO_INCREMENT,
    c.COLUMN_NAME,
    c.DATA_TYPE,
    c.IS_NULLABLE,
    c.COLUMN_DEFAULT,
    c.CHARACTER_MAXIMUM_LENGTH
FROM 
    INFORMATION_SCHEMA.TABLES t
    JOIN INFORMATION_SCHEMA.COLUMNS c 
        ON t.TABLE_NAME = c.TABLE_NAME 
        AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
WHERE 
    t.TABLE_SCHEMA = 'your_database'
    AND t.TABLE_TYPE = 'BASE TABLE'
ORDER BY 
    t.TABLE_NAME, c.ORDINAL_POSITION;
避坑指南:我曾经在生产环境直接连MySQL主库查元数据,结果把主库IO打满了。后来我改成连只读从库,或者单独部署一个元数据采集服务,定时拉取,避免对业务库造成影响。

4.3 统一元数据模型:怎么把“三张皮”缝成一件衣服

Hive、Kafka、MySQL的元数据格式完全不同。Hive有数据库、表、分区;Kafka有Topic、Schema、分区;MySQL有库、表、字段、索引。怎么统一?

我的做法是设计一个通用元数据模型,把不同数据源的元数据映射成统一的结构。

数据源类型 源对象 映射到统一模型 关键属性
Hive 数据库.表 Catalog.Schema.Table 存储格式、分区字段、文件数
Kafka Topic Catalog.Schema.Topic 分区数、副本数、消息保留时间
MySQL 数据库.表 Catalog.Schema.Table 引擎、自增ID、索引信息

统一模型的核心字段包括:

  • catalog:数据源实例标识,比如“hive_prod”、“kafka_online”
  • schema:命名空间,Hive的数据库、Kafka的集群、MySQL的库
  • entity:实体名,表或Topic
  • entity_type:TABLE / TOPIC / VIEW
  • fields:字段列表,每个字段包含name、type、description、nullable
  • properties:扩展属性,JSON格式,存放各数据源特有的信息

你想想看,有了这个统一模型,你的数据质量看板就可以一套规则引擎处理所有数据源。不管是Hive表字段非空校验,还是Kafka消息Schema兼容性检查,底层都是同一个元数据接口。

4.4 元数据采集与同步:增量还是全量?

元数据不是一成不变的。Hive表会新增分区,Kafka Topic会升级Schema,MySQL表会加字段。所以你需要一个定时采集+增量更新的机制。

我个人习惯的做法:

  1. 首次全量采集:把所有数据源的元数据拉一遍,存入元数据中心。
  2. 定时增量采集:每隔5-10分钟,对比上次采集时间,只拉取变更的部分。
  3. 变更事件推送:如果数据源支持事件通知(比如MySQL的Binlog、Kafka的Schema变更事件),优先用事件驱动,实时更新。
关键点:增量采集的核心是“版本号”或“变更时间戳”。Hive Metastore的TBL_ID是递增的,MySQL的UPDATE_TIME字段可以判断表是否变更。Kafka Schema Registry每次注册新版本都会递增version。

4.5 整体架构:一张图看懂元数据中心

说了这么多,我们来画一张架构图。这张图展示了我常用的元数据中心设计,包括数据源接入层、采集层、存储层和服务层。

元数据中心整体架构图 数据源层 Hive Metastore 表结构 · 分区 · 存储格式 Kafka Schema Registry Topic · Schema · 版本 MySQL INFORMATION_SCHEMA 库 · 表 · 字段 · 索引 采集层 元数据采集调度器 全量采集 · 增量对比 · 变更事件监听 存储层 统一元数据存储 通用模型表 · 字段映射 · 版本历史 · 血缘关系 存储引擎:MySQL / Elasticsearch / HBase 服务层 元数据查询API RESTful · 字段搜索 · 血缘追溯 变更事件推送 Webhook · 消息队列 · 实时通知 数据质量看板集成 规则绑定 · 监控配置 · 报告生成 说明:采集层定时从各数据源拉取元数据,转换为统一模型后存入存储层,服务层对外提供API和事件推送

4.6 落地避坑:我踩过的三个坑

最后,分享几个我在元数据中心落地过程中踩过的坑,希望能帮你少走弯路。

坑一:元数据采集频率太高
我曾经把Hive Metastore的采集频率设成1分钟一次。结果Metastore的MySQL连接数被打满,Hive查询都受影响。后来改成10分钟一次,加上增量对比,问题解决。
坑二:忽略字段描述
元数据采集只拉了字段名和类型,没拉注释。结果数据质量看板上线后,业务方看着“col_1”、“col_2”一脸懵。后来我强制要求每个字段必须有描述,否则标记为“待补充”。
坑三:Schema兼容性只检查不告警
Kafka Schema升级后,我检查了兼容性,但没通知下游。结果消费者消费失败,数据延迟了2小时才发现。后来我加了Webhook,Schema变更自动发到企业。