揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

这篇具有很好参考价值的文章主要介绍了揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据资产现在需要接入数栈内部相关应用的时候,支持查看血缘的类型从表、离线任务增加到需要表、离线任务、实时任务、API任务、指标、标签等,需要支持数栈现有的所有应用任务,最终实现在数据资产平台查看任务的完整应用链路。

虽然增加不同的任务,现阶段资产实现的血缘大体上能够满足需求,但是也会出现问题,因此需要进行技术革新。本文将聚焦资产血缘的实现方案,并介绍袋鼠云数栈在数据血缘建设过程中所遇到的挑战和技术实现。

资产血缘的当前问题

现阶段血缘展示内容重复高

在资产的 A 任务血缘链路中,C/D 任务下游均为 E 任务,当我们同时打开了 C/D 任务的下游节点,就会发现大量的重复节点出现,但本质上他们是一模一样的任务节点,如下图。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

当一条血缘上的任务越多,出现上述问题的概率增大,会导致画布内容显示的都是重复节点,查看血缘关系效率低下。

期望能够做到同一个节点只在画布中展示一次,在这个节点存在于画布中时,后续再有相同节点就做共用,如下图。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

逆向血缘的展示

先简单介绍一下,何为逆向血缘?用 API 任务举例子来说:

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

在 API 平台中,通过 DQL 模式使用两张表创建一个 API,在资产平台以 API 任务进入血缘就会展示如下图的血缘关系。如果 Table A 已经同步到了资产平台,以 Table A 表进入血缘,希望展示如下图的血缘关系。

由于 API 是由 Table A/B 共同生成的,因此需要在 API 左侧展示加号,能够将 Table B 加载出来,这就是逆向血缘,也是全链路实现的重要一环。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

相似数据源

当同一个数据源被不同的引擎连接之后,会产生不同的数据源A或数据源A1,但是实际上底层是同一个数据源,被我们称之为相似数据源。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

此时任务1和任务2并不会有相关联系,但其实它两用的是相同的底层表,展示是不符合期望的,希望能够在血缘展示上将其视为同一张表,相关的任务也能关联展示。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

上述问题成为资产实现全链路血缘需要去实现或者优化的当前血缘方案的理由,下文将给出对应问题的解决方案。

资产血缘实现解决方案

前置内容了解

● 任务血缘数据结构

interface ITaskKinShip {
  metaId:  number;                  // 元Id
  metaType: number;                 // 元类型
  metaDataInfo: object;             // 表、api、任务、标签等的元数据信息的元数据信息
  lineageTableId:  string;          // 血缘Id
  tableKey: string;                 // 表key source.db.table
  sonIds: number[];                 // 子节点血缘定位Id list
  fatherIds: number[];              // 父节点血缘定位Id list
  sonLineage: ITaskKinShip[];       // 子表级血缘
  fatherLineage: ITaskKinShip[];    // 父表级血缘
  isOpen: boolean;                  // 是否存在逆向血缘
}

● 字段血缘数据结构

interface IColumn {
  columnId: string;             // 字段Id
  columnName: string;           // 字段类型
  columnType:  string;          // 字段
  lineageColumnId: string;      // 字段血缘定位Id
  withManual: boolean;          // 是否手动维护
  withMasked: boolean;          // 是否脱敏字段
  sonIds: number[];             // 子ID
  fatherIds: number[];          // 父ID
  columnKey: string;            // 字段key source.db.table.column
}

interface IColumnKinShip extends ITaskKinShip {
  columns: IColumn[];           // 字段血缘
}

● 血缘关系图

· 初始化时默认展示3层:即只展示以数据表本节点为中心,上下游分别的一个节点,共3层

· 节点可扩展:点击“+”按钮,在节点前方或后方再展示出3个节点;点击“-”按钮,断开该“-”按钮对应的连线

· 右键:在非中心节点上,添加右键菜单“查看此节点血缘”;鼠标右键可查看当前节点血缘,以该节点为中心的血缘

整体思路

● 实现节点共用

我们想要去实现节点共用,就会去判断当前节点是否已经存在于 graph 中,如果存在我们就不再渲染节点,否则就去渲染节点,这样就可以实现节点只被渲染一次。

对于每一个节点信息来说,tableKey 都是唯一的,因此我们将 tableKey 作为每一个 vertex 的唯一标识,在创建 vertex 时,传入 tableKey 作为唯一标识。

createVertex = (treeData) => {
    const { graph, Mx } = this.GraphEditor;
    const rootCell = graph.getDefaultParent();
    const style = this.GraphEditor.getStyles(treeData);
    const doc = Mx.mxUtils.createXmlDocument();
    const tableInfo = doc.createElement('table');
    const { vertex, fatherLineage, sonLineage, ...newData } = treeData;
    tableInfo.setAttribute('data', JSON.stringify(newData));
    // 通过 tableKey 在当前 graph 查找 vertex
    const cell = graph.getModel().getCell(treeData.tableKey);
    // 如果能够找到就不创建新的 vertex,否则创建
    const newVertex =
        cell ||
        graph.insertVertex(
            rootCell,
            treeData.tableKey,
            tableInfo,
            20,
            20,
            VertexSize.width,
            VertexSize.height,
            style
        );
    return { rootCell, style, vertex: newVertex };
}

如果我们采用上述的想法,那这个节点可以同时成为中心节点的上游节点和下有节点,甚至就是中心节点。因此我们需要更改我们存储节点的结构,需要存储节点作为上游节点的信息以及作为下有节点的信息。

当从后端请求来数据之后,我们需要对数据做一个整理,不再存放在 state 中,而是将其存在以 tableKey 为 key,名为 vertexMap 的 Map 对象中。后续的渲染对象,也根据 vertexMap 去做渲染。

vertexMap 的定义如下,主要用于存储 tableKey 为键值的节点信息。

vertexMap = new Map<
    string,
    { 
        rootData?: ITaskKinShip;      // 节点作为根节点存储的数据
        parentData?: ITaskKinShip;    // 节点作为上游节点存储的数据
        childData?: ITaskKinShip;     // 节点作为下游节点存储的数据
        canDeleteData?: any;          // 能够被删除的数据,用于删除的时候判断
    }
>()

通过 checkData 方法来将后端给的数据处理到 vertexMap 中,重点是需要整合同为上游节点或者同为下游节点的数据。

checkData = (treeData: ITaskKinShip) => {
    const {
        tableKey,
        isRoot = false,
        isParent,
        sonIds,
        fatherIds,
        sonLineage,
        fatherLineage,
    } = treeData;
    const mapData = this.vertexMap.get(tableKey);
    // 标识为根结点
    if (mapData?.rootData) return true;
    // 判断是上游节点还是下游节点
    const newKey = isRoot ? 'rootData' : isParent ? 'parentData' : 'childData';
    // 如果不存在上游节点/下有节点的数据直接赋值
    if (!mapData?.[newKey])
        return this.vertexMap.set(tableKey, { ...mapData, [newKey]: treeData });
    // 否则,需要整合相同节点的 sonIds/fatherIds sonLineage/fatherLineage,为后续的判断提供依据
    const nodeData = mapData[newKey];
    const {
        sonIds: exitSonIds,
        fatherIds: exitFatherIds,
        fatherLineage: exitFatherLineage,
        sonLineage: exitSonLineage,
    } = nodeDat
    nodeData.sonIds = [...new Set(sonIds.concat(exitSonIds).filter((id) => id !== 'exist'))];
    nodeData.fatherIds = [
        ...new Set(fatherIds.concat(exitFatherIds).filter((id) => id !== 'exist')),
    ];
    nodeData.sonLineage = [...new Set(sonLineage.concat(exitSonLineage))];
    nodeData.fatherLineage = [...new Set(fatherLineage.concat(exitFatherLineage))];
    nodeData.isChildShow = nodeData.isChildShow || treeData.isChildShow;
    nodeData.isParentShow = nodeData.isParentShow || treeData.isParentShow;
    this.vertexMap.set(tableKey, { ...mapData, [newKey]: nodeData });
};

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

上述是对血缘数据的处理,对于整个血缘图节点如下图:

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

● 如何控制节点扩展

当我们的每一个节点被渲染出来的时候,可能会存在按钮,可以展开上下三层的更多节点。由于节点共用以及需要支持逆向血缘的需求,因此按钮的状态会发生变化:

· 中心节点不会有按钮

· 中心节点下游节点有下游血缘时,有右侧按钮;存在逆向血缘时,有左侧按钮

· 中心节点上游节点有上游血缘时,有左侧按钮;存在逆向血缘时,有右侧按钮

注意是否存在逆向血缘,通过后端接口的 isOpen 标识来做判断。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

对于普通的 + 号来说,点击 + 号时,一次性会请求三层数据;对于逆向血缘的 + 号来说,一次性请求一层数据;点击 - 号来说,会将其后续的节点都收起来。

对于每一个节点来说,我们会添加 isParentShow/isChildShow 来表示当前节点上下游是否展开。

· 收起操作:如果点击的按钮处于展开状态,则将相关联节点收起。点击右边按钮时,对当前节点设置 isChildShow = false;点击左边按钮时,对当前节点设置isParentShow = false。

· 展开操作:如果点击的按钮处于收起状态,则将相关联节点展开。点击右边按钮时,如果不存在 sonLineage 说明尚未获取过血缘节点信息,向后端发起请求;否则对当前节点设置isChildShow = true。对于左边按钮也是如此。

相关的判断流程如下图:

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

● 如何处理增加/删除节点

我们可以采用右键去插入血缘表或者插入影响表。当我们去做插入血缘操作的时候,也分为两种情况,判断当前节点是否已经加载过上游、下游节点,如果加载过,直接把新血缘数据添加到 vertexMap 中;否则,向后端发起请求,获取当前节点的血缘数据。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

对于删除节点来说,不能够再像之前那样找到其父级节点删除对应节点之后再重新渲染画布,对于节点共用来说,这会出现问题。在资产平台来说,血缘节点分为两种,一种是通过 sqlParser 解析出来的,不能够进行手动删除;另一种是我们通过右键手动添加的,是可以删除的。

当我们遇到手动添加和解析出来的节点共用时,我们进行删除就需要特殊处理,将解析出来节点的相关信息保留下来。

在我们插入节点的时候,我们会根据后端标识位 withManual 得知是解析还是手动添加的,使用 canDeleteData 维护手动添加的节点父级信息。

if (withManual) {
    canDeleteData.push({
        lineageTableId: obj.lineageTableId,
        parentTableKey: obj.tableKey,
    });
}

在最开始我们实现节点共用的时候,我们将同一个节点的 sonIds/sonLineage 等信息通过 checkData 方法整合在一起,删除的时候应该配合 canDeleteData 把对应的数据一同清理掉。

删除操作的大致流程如下图:

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

● 处理特殊的类型节点

由于承接了各个应用的血缘展示,不乏一些特殊的节点,常规的方案无法满足节点展示需求,因此需要做特殊处理。

对于实时的 FlinkSQL 就是需要特殊处理的,虚线框中的是 FlinkSQL 的相关内容,和映射源表、映射结果表连接的节点需要用虚线连接。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

对于 FlinkSQL 的相关数据后端存放于 metaDataInfo 中,parentFlinkInfos 表示映射源表,sonFlinkInfos 表示映射结果表。

揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现

因此根据 FlinkSQL 所处的位置不同,会有不同的渲染逻辑:

· 中心节点

渲染 parentFlinkInfos 创建 parentFlinkTableNode 与 FlinkSQL 节点实线连接,parentFlinkTableNode 再和上游节点使用虚线连接;渲染 sonFlinkInfos 创建 sonFlinkTableNode 与 FlinkSQL 节点实线连接,创建的 sonFlinkTableNode 再和下游节点使用虚线连接。

· 上游节点

渲染 sonFlinkInfos 创建 sonFlinkTableNode 与当前节点虚线连接,渲染 FlinkSQL 节点和 sonFlinkTableNode 实线连接,渲染 parentFlinkInfos 创建 parentFlinkTableNode 与 FlinkSQL 节点实线连接,parentFlinkTableNode 再去和别的上游节点使用虚线连接。

· 下游节点

渲染 parentFlinkInfos 创建 parentFlinkTableNode 与当前节点虚线连接,渲染 FlinkSQL 节点和 parentFlinkTableNode 实线连接,渲染 sonFlinkInfos 创建 sonFlinkTableNode 与 FlinkSQL 节点实线连接,sonFlinkTableNode 再去和别的下游节点使用虚线连接。

● 相似数据源

在相似数据源上,前端并没有对其做过的处理,均为后端判断为相似数据源给到前端做相关展示。

● 字段级血缘

上述讲的都是表级血缘的实现,字段级血缘也实现了节点共用等功能,整体思路和表级血缘一致。唯一需要注意的是实时的字段血缘,如果存在两个结果表时,会存在多个中心节点,所以需要遍历,渲染两个中心节点。

《数栈产品白皮书》:https://www.dtstack.com/resources/1004?src=szsm

《数据治理行业实践白皮书》下载地址:https://www.dtstack.com/resources/1001?src=szsm

想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szbky

同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:30537511,项目地址:https://github.com/DTStack文章来源地址https://www.toymoban.com/news/detail-586623.html

到了这里,关于揭秘|来看看袋鼠云数栈内部的资产血缘方案设计与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 性能提升30%!袋鼠云数栈基于 Apache Hudi 的性能优化实战解析

    Apache Hudi 是一款开源的数据湖解决方案,它能够帮助企业更好地管理和分析海量数据,支持高效的数据更新和查询。并提供多种数据压缩和存储格式以及索引功能,从而为企业数据仓库实践提供更加灵活和高效的数据处理方式。 在金融领域,企业可以使用 Hudi 来处理大量需要

    2024年02月09日
    浏览(45)
  • 袋鼠云数栈 DataOps 数据生产力实践,实现数据流程的自动化和规范化

    袋鼠云产品团队在帮助企业进行数字化转型实践的过程中,发现很多企业在数据生产链路上都有着相同的问题。包括数据团队聚焦于业务需求短期内的快速交付,内部缺少自顶向下的数据生产管理制度,在数据标准、数据生产流程到研发规范的各个层面均存在不完善与不规范

    2024年02月13日
    浏览(47)
  • 袋鼠云数栈UI5.0设计实战|B端表单这样设计,不仅美观还提效

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。 本文作者:大喜 相关文章:袋鼠云出品!数栈UI 5.0全新体验升级,设计背后的故事 表单是B端产品中最常见的组件之一,主要⽤于数据

    2024年02月03日
    浏览(40)
  • 袋鼠云产品功能更新报告05期|应有尽“优”,数栈一大波功能优化升级!

    这段时间,我们对产品本身以及客户反馈的一些问题进行了持续的更新和优化,包括对离线平台数据同步功能的更新,数据资产平台血缘问题的优化等,力求满足不同行业用户的更多需求,为用户带来极致的产品使用体验。 以下为袋鼠云产品功能更新报告第五期内容,更多探

    2024年02月04日
    浏览(49)
  • 袋鼠云产品功能更新报告06期|数栈产品功能升级,做产品我们是认真的!

    2023年已过半,袋鼠云开发团队和产品团队对数栈产品本身以及客户反馈的问题和痛点进行了持续性的更新和优化,包括对 EasyMR 监控告警功能的更新,以及对离线开发平台表生命周期逻辑的优化等,力求满足不同行业用户的更多需求,为用户带来极致的产品使用体验。 以下为

    2024年02月15日
    浏览(42)
  • 揭秘新一代云数仓技术架构与最佳实践

    从传统数仓到湖仓一体,历经三十多年发展,技术的浪潮快速迭代,以云原生数仓为中心的现代数据栈时代已然到来。 背后的核心的原因在于,企业正在加速走向数字化、智能化,对数据的应用也提出了全新要求,特别是对数据的实时分析、实时部署需求更加的强烈,而云数

    2024年02月09日
    浏览(53)
  • 袋鼠云代码检查服务,揭秘高质量代码背后的秘密

    质量是产品的生命线,代码检查是软件开发过程中至关重要的一环,它可以帮助我们发现并纠正潜在的错误,提高软件质量,降低维护成本。 在袋鼠云产品中也存在这个问题,由于离线数据开发人员 SQL 水平不一,导致代码书写混乱、SQL 代码运行问题较多。本文将介绍在离线

    2024年02月08日
    浏览(58)
  • 江铃晶马 X 袋鼠云:搭建企业级数据资产中心,推进打造“智数晶马”

    江铃集团晶马汽车有限公司(简称:晶马汽车)系江铃集团全资子公司,属集团六大整车企业之一。晶马汽车是以大、中、轻型客车(含新能源客车)、乘用车(不含轿车)、专用车等车型研发、生产、销售和服务为核心的整车企业,涉及客运、公交、旅游、通勤、旅居车、

    2024年02月04日
    浏览(49)
  • 【惊喜揭秘】xilinx 7系列FPGA时钟区域内部结构大揭秘,让你轻松掌握!

      本文对xilinx 7系列FPGA的时钟布线资源进行讲解,内容是对ug472手册的解读和总结,需要该手册的可以直接在xilinx官网获取,或者在公众号回复“ xilinx手册 ”即可获取。   7系列器件根据芯片大小不同,会有8至24个时钟区域,如图1所示,图中的每个虚线框就表示一个时钟

    2024年02月03日
    浏览(68)
  • “深入解析JVM:Java虚拟机内部原理揭秘“

    标题:深入解析JVM:Java虚拟机内部原理揭秘 摘要:本文将深入探讨Java虚拟机(JVM)的内部原理,包括JVM的架构、运行时数据区域、垃圾回收机制以及即时编译器等重要组成部分。通过对JVM内部原理的解析,我们可以更好地理解Java程序在运行时的行为,并通过示例代码来说明

    2024年02月12日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包