前言
元数据是数据平台的衍生数据,比如调度任务信息,离线hive表,实时topic,字段信息,存储信息,质量信息,热度信息等。在数据平台建设初期,这类数据主要散落于各种平台子系统的数据库中,例如HiveMetaStore,调度系统db等,在这个时期数据平台主要以服务业务数据需求为主,平台也以管理表,写ETL,配置调度这类功能性需求作为重点,对于这些散落元数据的收集与统一管理并没有太过强烈的诉求。
随着数据平台业务规模的增长,平台会沉淀大量的数据表,调度任务等元数据。由于前期快速的业务发展产生大量数据管理成本,存储计算成本。此时会逐步产生诸如模型规范治理、模型变更影响,指标异动定位,重复建设治理等需求场景。基于这些场景需求,此时数据平台仅提供数据开发相关的功能便难以满足业务需求,需要建设以数据地图(找数),血缘地图(定位数据链路),影响分析工具,资产看板,治理工具等一系列偏向于事后的信息查询、治理相关产品工具。
由于先前元数据的散落,导致系统间数据相互耦合,边界不清楚,无法以全局视角观察分析平台数据资产,无法串联数据之间的生产加工关系。于是建设起完善可靠的元数据服务成为后续满足数据发现,数据治理业务的关键。
背景
B站的数据平台元数据建设之初,由于对元数据的业务理解不够深入,人力投入有限,实现方案采用的是针对特定需求深度定制化。比如需要某类Hive表的字段信息,那么针对这个场景,设计一批hive表与字段的元数据表,通过直连HMS拉全量数据,定制业务逻辑消费HMS的Binlog进行变更同步,再通过暴露一批查询表字段的HTTP接口,提供给需求方进行查询。
基于这种模式,虽然短期也能满足需求,但是暴露出了两个大问题:1.灵活性差,实现非常定制,难以支撑频繁出现的边界场景??(笔者不是很懂边界场景什么意思),只能针对新需求做排期开发,严重拖慢业务迭代速度 2.开发维护成本高,大量定制的采集逻辑、异构的元数据表、支持各种业务场景的接口,在有限的人力资源上难以支撑,还要随时面对元数据模型变更的问题,采集质量的问题。
在这种状态下,也出现了一些必然结果,由于无法快速支持业务需求,需求方通常会自建离线元数据来跑通业务,产生了重复建设和后期治理的问题。由于开发维护成本高,支持源数据业务的同学疲于应对各种需求,压力大,还要兼顾各类线上的元数据质量问题排查运维。
所以,体系化建设元数据的目标之一就是统一元数据。即以统一的元数据模型,统一的采集方式,统一的存储方式,统一的查询方式支撑上层元数据业务需求。
系统总览
统一元数据模型
元数据模型需要满足3点要求:
1.统一标识元数据资源
2.描述所有类型的元数据资源
3.描述上述各类元数据资源之间的各种类型关系
我们在这部分借鉴了业界的一些通用方案,以标识协议URN+实体+关系进行了统一元数据模型的构建。
统一标识协议URN
URN = 协议域 + 业务域 + 资源类型 +唯一资源ID
每个域之间以 [ : ] 进行分隔
其中协议域全局固定为urn;对于数据平台内部的资源业务域统一为datacenter;资产类型为协商约定,由此文档统一管理;唯一资源ID则由各个资产的定义方自行约定。
基于URN协议,b站已经约定了16类的资源类型,以下列举几类作为示例:
类型名称 | 类型说明 | 唯一资源ID说明 | 举例 |
workspace | 工作空间 | 工作空间名称 | urn:datacenter:workspace:xxx |
udf | UDF | UDF名称 | urn:datacenter:udf:max |
tab | 表 | 源.库.表 | urn:datacenter:tab:Hive1.ods.video_live_origin_publisher |
metric | 指标 | 指标id | urn:datacenter:metric:123 |
page | BI报表 | 观远报表id | urn:datacenter:page:g43f230943da746db0942f1 |
ds | 数据源 | 数据源名称 | urn:datacenter:ds:Tidb_datacenter-dwboss-jssz_akuya |
dqc | dqc | dqc id | urn:datacenter:dqc:1234 |
col | 字段 | 源.库.表.字段 | urn:datacenter:col:Hive1.bili_yyzx.ysh_up_tag1 |
baseline | 基线 | 基线id | urn:datacenter:baseline:364 |
archerJob | 调度任务 | 任务id | urn:datacenter:archerJob:5203165 |
表的URN定义,我们认知中的表,可以来源于平台内部,比如常见的Hive,Clickhouse表等,也可以来源于平台外部,比如业务的Mysql,TiDB,还有一些是针对类似KV结构映射出的逻辑表。
由于再在血缘场景中,我们需要打通这些跨域类型的数据表的关系,所以需要站在全局的视角对他们进行统一标识。我们采取的方案,使用tab作为这些数据表统一类型,再以源.库.表三段式作为唯一资源ID对各类数据源的进行表述,引申到字段同理,是以源.库.表.字段四段式进行表述。
需要注意的是,如果要使用这种表达方式,必须满足一个前提:具备统一的数据源管理,保障相同来源的数据源名称唯一且不发生变更,比如使用同一个mysql集群下的数据库中的表,必须在全部业务流程中,收敛为使用同一个数据源。这里会涉及到了关于数据源命名规范的问题,不多做展开。
两个概念特别讲解一下
实体的Aspect
在通常的理解中,一个实体的全部信息应该来源于一个系统,这样当进行一类资源的采集时,我们只需要找到那个系统去同步,
关系的BuilderURN