开源 DataHub:LinkedIn 的元数据搜索和发现平台
对于任何依赖大量数据来制定数据驱动决策的公司来说,快速找到所需的数据至关重要。 这不仅会影响数据用户(包括分析师、机器学习开发人员、数据科学家和数据工程师)的生产力,还会对依赖于高质量机器学习 (ML) 管道的最终产品产生直接影响。 此外,实施或构建机器学习平台的趋势自然提出了一个问题:内部发现特征、模型、指标、数据集等的方法是什么。
在本文中,我们将讨论如何在开放许可下发布数据源
WhereHows 现在是一个数据中心!
LinkedIn 的元数据团队之前介绍过
开源方法
WhereHows 是 LinkedIn 最初用于查找数据及其来源的门户,最初是一个内部项目; 元数据团队打开了它
第一次尝试:“开源第一”
我们最初遵循“开源优先”的开发模型,其中大多数开发发生在开源存储库中,并针对内部部署进行更改。 这种方法的问题在于,代码总是先推送到 GitHub,然后再进行内部全面审查。 在对开源存储库进行更改并进行新的内部部署之前,我们不会发现任何生产问题。 如果部署不佳,也很难确定罪魁祸首,因为更改是批量进行的。
此外,该模型在开发需要快速迭代的新功能时降低了团队的生产力,因为它迫使所有更改首先推送到开源存储库,然后推送到内部存储库。 为了减少处理时间,可以首先在内部存储库中完成所需的修复或更改,但是当将这些更改合并回开源存储库时,这成为一个巨大的问题,因为这两个存储库不同步。
与全功能自定义 Web 应用程序相比,该模型对于共享平台、库或基础设施项目更容易实现。 此外,此模型非常适合从第一天开始开源的项目,但WhereHows 是作为完全内部的 Web 应用程序构建的。 完全抽象掉所有内部依赖项确实很困难,因此我们需要保留内部分叉,但保留内部分叉并开发大部分开源代码并不太有效。
第二次尝试:“内在第一”
**作为第二次尝试,我们转向“内部优先”开发模式,其中大多数开发都在内部进行,并定期对开源代码进行更改。 尽管该模型最适合我们的用例,但它存在固有的问题。 直接将所有差异推送到开源存储库,然后稍后尝试解决合并冲突是一种选择,但这很耗时。 在大多数情况下,开发人员尽量不要在每次检查代码时都这样做。 因此,批量执行此操作的频率会大大降低,从而使以后解决合并冲突变得更加困难。
第三次就成功了!
上述两次失败的尝试导致WhereHows GitHub 存储库在很长一段时间内仍然过时。 团队不断改进产品的功能和架构,使得WhereHows for LinkedIn的内部版本变得比开源版本更加先进。 它甚至还有一个新名称——DataHub。 基于之前的失败尝试,团队决定开发一个可扩展的长期解决方案。
对于任何新的开源项目,LinkedIn 的开源团队都会建议并支持一种开发模式,其中项目的模块完全以开源方式开发。 版本化工件被部署到公共存储库,然后使用以下命令重新签入内部 LinkedIn 工件
然而,成熟的后端应用程序(例如 DataHub)将需要大量时间才能达到此状态。 这也排除了在所有内部依赖关系完全抽象之前开源完全工作的实现的可能性。 这就是为什么我们开发了一些工具来帮助我们更快、更轻松地做出开源贡献。 该解决方案对元数据团队(DataHub 开发人员)和开源社区都有好处。 以下各节将讨论这种新方法。
开源出版自动化
Metadata 团队对开源 DataHub 的最新方法是开发一个自动同步内部代码库和开源存储库的工具。 该工具包的高级功能包括:
以下小节将深入研究上述具有有趣问题的函数。
源代码同步
与开源版本的 DataHub 不同,DataHub 是单个 GitHub 存储库,LinkedIn 版本的 DataHub 是多个存储库的组合(内部称为
图 1:存储库之间的同步 LinkedIn 数据中心 和一个存储库 数据中心 开源
为了支持自动构建、推送和拉取工作流程,我们的新工具会自动创建与每个源文件相对应的文件级映射。 但是,该工具包需要初始配置,并且用户必须提供高级模块映射,如下所示。
{
"datahub-dao": [
"${datahub-frontend}/datahub-dao"
],
"gms/impl": [
"${dataset-gms}/impl",
"${user-gms}/impl"
],
"metadata-dao": [
"${metadata-models}/metadata-dao"
],
"metadata-builders": [
"${metadata-models}/metadata-builders"
]
}
模块级映射是一个简单的 JSON,其键是开源存储库中的目标模块,值是 LinkedIn 存储库中的源模块列表。 开源存储库中的任何目标模块都可以由任意数量的源模块提供。 要指示源模块中存储库的内部名称,请使用
{
"${metadata-models}/metadata-builders/src/main/java/com/linkedin/Foo.java":
"metadata-builders/src/main/java/com/linkedin/Foo.java",
"${metadata-models}/metadata-builders/src/main/java/com/linkedin/Bar.java":
"metadata-builders/src/main/java/com/linkedin/Bar.java",
"${metadata-models}/metadata-builders/build.gradle": null,
}
文件级映射由工具自动创建; 但是,它也可以由用户手动更新。 这是 LinkedIn 源文件到开源存储库中文件的 1:1 映射。 有几个与自动创建文件关联相关的规则:
- 在开源的目标模块有多个源模块的情况下,可能会出现冲突,例如相同的模块
完全质量控制网络 ,存在于多个源模块中。 作为一种冲突解决策略,我们的工具默认为“最后一个获胜”选项。 - “null”表示源文件不属于开源存储库。
- 每次开源提交或提取后,该映射都会自动更新并创建快照。 这对于识别自上次操作以来源代码中的添加和删除是必要的。
创建提交日志
开源提交的提交日志也是通过合并内部存储库的提交日志自动生成的。 下面是一个示例提交日志,显示了我们的工具生成的提交日志的结构。 提交清楚地表明该提交中打包了源存储库的哪些版本,并提供提交日志的摘要。 看看这个
metadata-models 29.0.0 -> 30.0.0
Added aspect model foo
Fixed issue bar
dataset-gms 2.3.0 -> 2.3.4
Added rest.li API to serve foo aspect
MP_VERSION=dataset-gms:2.3.4
MP_VERSION=metadata-models:30.0.0
依赖性测试
领英有
这是一种有用的机制,有助于防止任何破坏开源构建的内部提交,并在提交时检测到它。 如果没有这个,就很难确定哪个内部提交导致开源存储库构建失败,因为我们批量对 DataHub 开源存储库进行内部更改。
开源 DataHub 和我们的生产版本之间的差异
到目前为止,我们已经讨论了同步两个版本的 DataHub 存储库的解决方案,但我们仍然没有概述为什么我们首先需要两个不同的开发流的原因。 在本节中,我们将列出 DataHub 的公共版本和 LinkedIn 服务器上的生产版本之间的差异,并解释这些差异的原因。
差异的一个根源在于我们的生产版本依赖于尚未开源的代码,例如 LinkedIn 的 Offspring(LinkedIn 的内部依赖注入框架)。 Offspring 广泛用于内部代码库,因为它是管理动态配置的首选方法。 但它不是开源的; 因此我们需要找到开源 DataHub 的开源替代方案。
还有其他原因。 当我们根据 LinkedIn 的需求创建元数据模型的扩展时,这些扩展通常非常特定于 LinkedIn,可能无法直接应用于其他环境。 例如,我们为参与者 ID 和其他类型的匹配元数据提供非常具体的标签。 因此,我们现在已将这些扩展从 DataHub 的开源元数据模型中排除。 当我们与社区互动并了解他们的需求时,我们将在需要时开发这些扩展的通用开源版本。
易于使用和更容易适应开源社区也激发了两个版本的 DataHub 之间的一些差异。 流处理基础设施的差异就是一个很好的例子。 尽管我们的内部版本使用托管流处理框架,但我们选择对开源版本使用内置(独立)流处理,因为它避免创建另一个基础设施依赖项。
差异的另一个例子是在开源实现中使用单个 GMS(通用元数据存储)而不是多个 GMS。 GMA(通用元数据架构)是DataHub后端架构的名称,GMS是GMA上下文中的元数据存储。 GMA 是一种非常灵活的架构,允许您将每个数据构造(例如数据集、用户等)分发到其自己的元数据存储中,或者将多个数据构造存储在单个元数据存储中,只要注册表中包含数据结构映射即可GMS 已更新。 为了便于使用,我们选择了一个 GMS 实例,将所有不同的数据结构存储在开源 DataHub 中。
下表给出了两种实现之间差异的完整列表。
产品特点
领英数据中心
开源数据中心
支持的数据结构
1) 数据集 2) 用户 3) 指标 4) ML 功能 5) 图表 6) 仪表板
1) 数据集 2) 用户
数据集支持的元数据源
1)
Hive Kafka RDBMS
发布-订阅
汇流卡夫卡
流处理
托管
嵌入式(独立)
依赖注入和动态配置
领英后代
构建工具
Ligradle(LinkedIn 的内部 Gradle 包装器)
CI / CD
CRT(LinkedIn 的内部 CI/CD)
元数据存储
分布式多个GMS:1)数据集GMS 2)用户GMS 3)指标GMS 4)特征GMS 5)图表/仪表板GMS
单一 GMS 适用于:1) 数据集 2) 用户
Docker 容器中的微服务
图 2:架构 数据中心 *开源**
您可以在上图中看到 DataHub 的高级架构。 除了基础设施组件之外,它还有四个不同的 Docker 容器:
datahub-gms:元数据存储服务
数据中心前端:应用程序
datahub-mce-consumer:应用程序
数据集线器-mae-消费者:应用程序
开源存储库文档和
DataHub 上的 CI/CD 是开源的
开源 DataHub 存储库使用
每次提交到 DataHub 开源存储库时,所有 Docker 映像都会自动构建并使用“最新”标签部署到 Docker Hub。 如果 Docker Hub 配置了一些
使用数据中心
- 克隆开源存储库并使用提供的 docker-compose 脚本通过 docker-compose 运行所有 Docker 容器以快速启动。
- 使用还提供的命令行工具下载存储库中提供的示例数据。
- 在浏览器中浏览 DataHub。
主动追踪
未来的计划
目前,开源 DataHub 的每个基础设施或微服务都是作为 Docker 容器构建的,整个系统是使用
我们还计划提供在公共云服务上部署 DataHub 的交钥匙解决方案,例如
最后但并非最不重要的一点是,感谢开源社区中所有 DataHub 的早期采用者,他们对 DataHub 进行了 alpha 评级,并帮助我们发现问题并改进文档。
来源: habr.com