火山引擎DataLeap:3步打造“指标管理”体系,幸福里数据中心是这么做的
Posted 字节跳动数据平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了火山引擎DataLeap:3步打造“指标管理”体系,幸福里数据中心是这么做的相关的知识,希望对你有一定的参考价值。
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群
一家企业,为什么要搭建指标体系?
一句话总结来说,全面、合理的指标体系可以帮助企业统一目标,将业务环节量化,帮助策略执行落地、定位问题、调整方向。但指标体系建构并非易事,指标如何维护和更新、如何统一指标口径、指标如何能科学指导业务决策,是企业构建指标体系遇到的常见问题。
幸福里 APP 是抖音集团旗下集内容、社区、工具于一体的房产信息综合平台,致力于提供多样化房产资讯、定制找房需求。数据建设是幸福里数据 BP 的核心工作,其中指标建设与管理是其中重要一环。指标是量化分析和构建策略的基础,是业务决策重要依据之一,也是数据团队重要的数据资产,因此幸福里指标管理是团队关注的重点之一。
本篇文章将从业务背景、业务痛点、幸福里指标数据实践、效果收益四个方面,介绍幸福里如何通过火山引擎 DataLeap、DataWind 等数据产品,从 0-1 完成指标体系搭建,并获得显著收益。
一、业务背景
幸福里指标管理经历了两个阶段:
-
第一个阶段:幸福里业务快速迭代,数据侧以响应需求,快速支持业务迭代为主,指标没有统一的规范,粗放式管理,缺少指标拆解标准以及分类标准,导致指标一词多义、重复开发、指标冗余,容易出现数据质量问题。
-
第二个阶段:幸福里整体业务发展趋于稳定,精细化运营对数据提出了更大的挑战。当前,数据侧以解决数据效率和质量问题为优先,进一步加强体系化建设,制定指标建设规范。
幸福里指标体系建设和落地离不开数据工具的支持。一方面,幸福里需要将不同数据源的指标进行建模,形成数据集,以便满足可视化查询的需要;一方面,也需要统一的平台规范化指标管理流程,提升数据模型的复用性,保证核心指标口径一致,提高业务方使用体验的效果。
作为火山引擎数智平台旗下的产品,DataWind 支持业务线创建项目来存放数据集,支持对指标数据的可视化查询,而 DataLeap 具备一体化指标体系建设和管理的能力,提供指标命名及口径管理的工具, 支持导入多种数据源构建模型以及灵活选择指标构建方式,通过一个平台即可实现指标管理。
由此,DataLeap 和 DataWind 成为幸福里团队构建指标体系首选。
二、业务痛点
第一,线下文档维护指标体系,格式不统一、更新不及时、维护成本高
-
早期幸福里指标字典主要通过线下文档人工维护,并没有专门人员统一负责指标的管理;
-
指标维护碎片化,不同业务模块维护各自指标库,指标字典文档格式不统一;
-
相关人员缺少维护动力,新增或修改指标不及时,指标信息共享局限,无法触达幸福里所有用户。
以上问题给相关人员造成指标应用与管理上的压力,因此幸福里需要一个统一管理指标的平台,解决指标管理上的痛点。
第二,缺少指标分类和管理规范
在幸福里业务快速迭代过程中,数据侧为追求需求的快速支持,缺少指标的拆解或分类规范,存在重复开发、指标杂乱、一词多义、一义多词的问题,同时指标口径也没有在接口或数据做好透传,导致下游使用方不了解指标加工细节,进而可能使得数据质量问题频发。
三、应用实践
为什么要引入火山引擎 DataLeap?
-
通过 DataLeap 实现指标建设流程线上化、规范化,完成指标命名、指标新增与变更流程;
-
DataLeap 功能上更加全面和丰富,支持指标拆解、维度管理、词根管理等操作;
-
对业务侧使用更加友好,指标提需、口径变更进行流程化管理,可以串联起数据 BP、分析师和业务共同维护指标。
LOOK 数据中心实践:指标 100%覆盖
-
LOOK 是幸福里内部效率管理系统,除作业功能模块外,销售人员作业数据分析也是 LOOK 重要功能,通过数据及时监控内部员工作业效率,反馈核心大盘数据。该系统下新房数据整体通过 DataLeap 同步 DataWind 数据集方式提供数据服务。
步骤一:
提需流程 确定数据 BP 和业务团队指标开发合作机制,当前幸福里数据 BP 和业务团队合作模式如下:
-
指标开发
数据 BP 需要进行业务指标和分析维度的拆分,对于指标需先考虑指标字典中是否存在(防止重复开发),如果不存在, 需要拆解为原子指标+时间周期+修饰词, 并落入到指标平台;根据实际应用场景采用 DataWind 数据集或数据接口输出指标。
-
指标管理
由数据 BP 和 DA(或业务人员)共同维护。业务人员维护指标的业务口径并进行分类,业务定义将在 DataWind 看板或产品页面展示露出。
数据 BP 维护指标技术口径,进行指标模型关联,提供数据应用。通过 DataLeap 形成了数据 BP 和分析师协同管理指标的诉求,同时统一指标查询平台。
步骤二:指标录入与维护
幸福里以离线数仓主题划分数据域,同时将 DataLeap 词根管理功能进行应用,规范指标命名。针对需求涉及指标将指标拆解并划分合适的数据域,便于责任人统一管理。
指标拆解流程
指标拆解完成后,对原子指标、衍生指标和复合指标进行创建和技术口径维护,结合需求创建数据模型打通 DataWind 数据集和 mfs 数据服务。
DataLeap 的业务管理模块由数据分析师或产品进行维护,主要是管理指标的业务分类和定义业务口径。业务定义将在 DataWind 看板或产品页面展示露出。其中生产信息可以查看当前指标的模型应用,方面后续指标使用分析。
通过业务侧指标维护和指标的生产信息模块,便于业务侧查询和使用指标,同时对外展示便于各方理解。
词根管理
目前在录入指标过程中发现存在关键字定义不一致,一个中文名称有多个英文名称或者一个英文名称在不同业务线下有不同的中文含义。
为解决此类问题,幸福里对词根进行维护,录入指标之前先在词根管理的字段管理模块查看对应关键字是否已存在。
通过词根管理,将核心字段命名进行规范,避免命名不统一,解决了一词多义和一义多词的问题。
步骤三:指标应用 &口径透传
权限打通
同步 DataWind 数据集与数据授权,数据授权操作只需在 DataWind 数据集进行。
口径透传
DataLeap 同步 DataWind 数据集后,下游配置的数据看板可以将指标口径进行展示,也支持指标平台的跳转,便于下游使用方了解指标加工细节。
通过以上三个步骤,幸福里实现以下几个方面提升:
-
LOOK 数据模块整体通过指标平台提供指标服务,看板上查看看板涉及的指标的口径,降低 DA 口径同步的成本。
-
通过 DataLeap 减少数据 BP 重复开发、一词多义的问题,对应指标有相应责任人进行开发和管理,提高指标整体复用度。
-
观测数据时,用户可以通过指标平台了解每个展示指标的含义,整体提高数据的准确性。
-
指标字典从线下文档迁移到 DataLeap,通过线上配置化管理,降低数据分析师维护成本。
-
以前,数据集指标口径不清楚需要找数仓人员确认,再通过代码获取指标技术生产逻辑;现在,DataLeap 配置指标口径,支持在看板直接展示,节省解释指标口径的时间。
-
DataLeap 具备指标分组的能力,让指标更有层级性,方便查找和管理,提升效率。
四、效果收益:数据 oncall 解决超 40%
通过 DataLeap 指标平台,幸福里数据团队完成交易平台新房方向 p0 指标 100%覆盖,包括指标定义、模型配置、责任人等元信息维护。
DataLeap 指标平台和 DataWind 打通,便于使用方了解指标加工逻辑,通过 DataWind 看板对应按钮跳转 DataLeap 直接查看指标口径描述和绑定模型情况。
下面是目前幸福里在 DataLeap 的使用数据情况:
-
从数据上看,幸福里当前总录入指标数 504 个,模型数 28 个,交易平台整体指标覆盖率 60%。模型建设路径偏向业务驱动;业务维护率为 60%,和 DA 形成了一定的联动; 还需进一步在业务侧加强推广,提升指标消费热度。
-
业务使用上,支持指标口径在看板和线上页面展示透出,便于下游了解指标加工细节,数据口径反馈问题减少 40%。另外,指标平台作为幸福里各方查指标用指标的统一平台,提高指标查询和消费效率。
立即跳转火山引擎DataLeap了解更多
火山引擎DataLeap:揭秘字节跳动数据血缘架构演进之路
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群
DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成、开发、运维、治理、资产、安全等全套数据中台建设,降低工作成本和数据维护成本、挖掘数据价值、为企业决策提供数据支撑。
数据血缘是帮助用户找数据、理解数据以及使数据发挥价值的基础能力。基于字节跳动内部沉淀的数据治理经验,火山引擎 DataLeap 具备完备的数据血缘能力,本文将从数据血缘应用背景、发展概况、架构演讲以及未来展望四部分,为大家介绍数据血缘在字节跳动进化史。
背景介绍
1. 数据血缘是数据资产平台的重要能力之一
在火山引擎 DataLeap 中,数据资产平台主要提供元数据搜索、展示、资产管理以及知识发现能力。在数据资产平台中,数据血缘是帮助用户找数据、理解数据以及使数据发挥价值的重要基础能力。
2. 字节跳动的数据链路情况
数据来源
在字节跳动,数据主要来源于以下两部分:
- 第一,埋点数据:
主要来自 APP 端和 Web 端。经过日志采集后,这类数据最终进入到消息队列中。
- 第二,业务数据:
该类数据一般以在线形式存储,如 RDS 等。
中间部分是以 Hive 为代表的离线数仓:
该类数据主要来自消息队列或者在线存储,经过数据集成服务把数据导入离线数仓。经过离线数仓的数据加工逻辑,流转到以 ClickHouse 为代表的 OLAP 引擎。
另外,在消息队列部分,还会通过 Flink 任务或者其他任务对 Topic 分流,因此上图也展现了一个回指的箭头。
数据去向
主要以指标系统和报表系统为代表。指标系统包含重要且常用的业务指标,如抖音的日活等。报表系统是把指标以可视化形式展现出来。
数据服务
主要通过 API 提供数据,具体而言,从消息队列、在线存储、下游消费以及上图右侧所示的数据流转,都涵盖在数据血缘范围内。
血缘发展概况
接下来介绍血缘在字节跳动的三个发展阶段。
第一阶段:2019 年左右开始
第一阶段主要提供数据血缘基础能力,以 Hive 和 ClickHouse 为代表,支持表级血缘、字段血缘,涉及 10+元数据。
第二阶段:从 2020 年初开始
第二阶段引入了任务血缘,同时支持的元数据类型进行扩充,达到 15+。
第三阶段:从 2021 年上半年至今
在这一阶段,我们对整个元数据系统(即前文提到的资产平台)进行了 GMA 改造,同步对血缘架构进行全面升级,由此支持了更丰富的功能,具体包括:
- 首先,元数据种类扩充到近 30 种且时效性提升。之前以离线方式更新血缘数据,导致数据加工逻辑变化的第二天,血缘才会产生变化。目前,基于近实时的更新方式,数据加工逻辑在 1 分钟内即在血缘中体现。
- 其次,新增血缘消费方式的变更通知。由于该版本支持实时血缘,业务方产生及时了解血缘变化的需求,变动通知功能就是把血缘变化情况以消息队列的形式告知业务方。
- 再次,支持评估血缘质量。新增一条链路,专门服务于血缘数据质量。
- 最后,引入标准化接入方式。为了减少重复工作、降低血缘接入成本,我们制定了详细的血缘接入标准,业务方数据均以标准化方式接入。
以上就是整体的发展情况,目前处于第三个版本当中。
数据血缘架构的演进
接下来介绍血缘架构的演进。
- 第一版血缘架构:建立血缘基本能力,初探使用场景
血缘架构
- 在数据来源方面,目前血缘主要包括两个数据来源(见上图左上角):
第一,数据开发平台:用户在开发平台写任务,并对数据加工,由此产生血缘数据。
第二,追踪数据:第三方平台(即任务平台)对用户埋点等数据进行计算,也会产生血缘信息。
- 在血缘加工任务方面(见上图中间部分):
这部分会对任务进行血缘解析,产生血缘快照文件。由于第一版采用离线方式运行,每天该血缘任务均会生成对应的血缘快照文件。我们通过对比前后两天的血缘快照文件,来获取血缘的变更情况,然后把这些变更加载到图中。
除此之外,血缘中涉及的元数据会冗余一份,并存储到图里。
- 在血缘存储方面(见上图右边部分),除了图数据库之外,血缘本身也会依赖元数据的存储,如 Mysql 以及索引类存储。
- 在血缘消费层面,第一版只支持通过 API 进行消费。
最后总结该版本的三个关键点:
- 血缘数据每天以离线方式全量更新。
- 通过对比血缘快照来判断血缘更新操作,后面将为大家详细解答为什么要通过对比的方式。
- 冗余一份元数据存储到图数据库中。
存储模型
图中上半部分为表级血缘,只包括一种类型节点,即表节点,比如 Hive 表、 ClickHouse 表等。
图中下半部分为字段血缘,第一版主要是提供构建血缘的基本能力,因此用彼此分离的两张图来实现。由于血缘中元数据进行了冗余,每个图里面的每个节点里面都存储表相关的元数据,包括业务信息以及其他信息。
除此之外,我们会预先计算一些统计信息,保存到图的节点中,如当前节点下游总节点数量、下游层级数量等。
采用预先计算的目的是为了“用空间换时间”,在产品对外展示的功能上可能要露出数据信息,如果从图里实时查询可能影响性能,因此采用空间换时间的方式来支持产品的展示。
- 第二版血缘架构:血缘价值逐步体现,使用场景拓宽
血缘架构
经过 1 年的使用,血缘在数据资产中的价值逐步体现,且不断有应用场景落地,由此我们进行了第二版本升级。升级点具体包括:
- 第一,去除第一版本中元数据冗余。元数据冗余在图提升了性能,但是可能导致 Metadata Store 的元数据不一致,给用户带来困扰。
- 第二,去掉了预计算的统计信息。随着血缘的数据量增多,预计算的信息透出不能给很好辅助用户完成业务判断,且导致任务负担重。比如,即使知道某一节点的下游数据量,还是要拉出所有节点才能进一步分析或决策。
- 第三,支持一条全新链路,在新增链路上,我们把血缘快照文件导入离线数仓,主要应用于两个场景:
离线分析场景或全量分析场景。
基于离线数仓的血缘数据实现数据监控,尽早发现血缘异常情况。
因此,从第二版开始,数据血缘新增了很多离线消费方式。
存储模型
第二个版本引入了全新血缘存储模型(如上图所示),并将第一个版本两张图融合成一张图,解决了无法通过表遍历字段血缘的问题。
除此之外,第二个版本还引入了任务类型节点,服务于以下三种遍历场景:
- 单纯遍历数据血缘,即从数据节点到数据节点。
- 数据血缘和任务血缘混合方式。
- 单纯任务之间血缘关系。
- 第三版血缘架构:血缘成为数据发挥价值的重要基础能力
血缘架构
2021 年初,火山引擎 DataLeap 数据血缘迭代到第三版,也成为公司内部数据发挥价值的重要基础能力。
服务于业务方对数据高质量要求,第三版升级点如下:
- 血缘数据来源:除了支持两个平台之外,还支持包括报表、第三方用户画像等其他平台 。
- 血缘任务:之前版本只支持每天定时运行的离线调度方式,第三版引入实时消费方式,支持实时解析血缘,并提取通用逻辑,复用离线血缘任务和实时血缘任务。
- 血缘解析:不同类型任务需要使用不同解析逻辑。在之前版本中,Hive SQL 任务和 Flink SQL 任务的解析逻辑是集成到血缘任务中。从第三版开始,我们把解析服务拆解成可配置的插件,实现了插件化。当某一种任务类型的血缘解析逻辑需要调整的时候,只用改动其中一个解析服务,其他解析服务不受影响,同时也让血缘任务更好维护。
- 元数据存储统一:只依赖图数据库和索引存储,同时支持从系统中把所有相关的数据导出离线数仓。
- 实时消费:血缘发生变更的信息会被同步到消息队列。
- 血缘的验证模块:使用方对血缘数据质量有高要求,因此第三版引入新的血缘的验证模块。
验证的前提是要有引擎埋点数据,该埋点数据能清楚知道某一个任务具体读取数据情况、写入数据情况
在离线数仓中,通过埋点数据与血缘数据中对比,生成血缘数据质量报表。
数据质量报表对血缘消费者开放,消费者能够清晰了解每个血缘链路准确性和覆盖情况。
- 血缘标准化接入:即让用户快速接入数据,不用每一种血缘接入都重复写逻辑。
存储模型
第三版血缘存储模型相对于前两版的升级点如下:
- 以任务为中心。黄色圆圈为任务节点,数据加工逻辑产生血缘,因此我们把数据加工逻辑抽象为任务节点,血缘的建立则以任务为媒介,任务成为血缘中心。也就是说,表 1、表 2、表 3 之间的血缘,是通过任务 a 完成构建。假设没有任务 a ,则三个表之间的血缘也不存在。
- 表血缘和字段血缘模型统一,在字段血缘之间没有具体任务的情况下,我们会抽象出虚拟的任务来统一模型。由此,任务和任务之间的血缘采用新的边来表示依赖关系。
重要特性
增量更新
在实时血缘基础上,我们还支持增量更新能力,即当某一个任务的加工逻辑发生变化时,只需要更新图中一小部分。
- 血缘创建:数据加工逻辑上线或开始生效,将被抽象为图数据库的操作,即创建一个任务节点和对应的数据节点,并创建两者之间的边。上图例子为表 1、表 2 和任务的边,以及任务和表 3 之间的边。
- 血缘删除:数据的加工逻辑发生了下线、删除或不生效。先在图里面查询该任务节点,把任务节点以及关联血缘相关的边删除。血缘存储模型以任务为中心,因此表 1、表 2 和表 3 之间的血缘关系也同步消失,这部分血缘即被删除。
- 血缘更新:任务本身没有发生上线或下线,但计算逻辑发生变化。例如,原本血缘关系是表 1、表 2 生成表 3,现在变成了表 2、表 4 生成表 3。我们需要做的如下:
解析出最新血缘状态,即表 2、表 4 到表 3 的血缘关系,与当前血缘状态做对比(主要对比该任务 a 相关的边),上图例子是入边发生变化,那么删除其中一条边,构建另外一条边,即可完成该任务节点的血缘更新。
如果面临以上血缘关系变化,但是没有该任务节点,应该执行哪些操作来更新血缘?由于只有血缘最新状态和当前状态,没有任务节点去获取最小单位的血缘关系,所以只能进行全量血缘或全图对比,才能得出边的变化情况,再更新到图数据库中。如果不进行全量血缘或全图对比,无法知晓如何删除条和创建条,导致血缘无法更新。这也是前两个版本需要进行血缘快照对比的原因。
血缘标准化
在火山引擎 DataLeap 中,通常把血缘数据接入抽象成一个 ETL 。
首先,血缘数据来源,即第三方平台血缘相关的数据,通常是一个数据加工逻辑或者称为任务。接着,对这些任务完成 KeyBy 操作,并与数据资产平台的任务信息做对比,确定如何进行任何创建、删除和更新。
在再完成过滤操作之后, 由 Lineage Parser 对创建、更新等任务进行血缘解析,得出血缘结果之后会生成表示图相关操作的 Event,最终通过 Sink 把数据写入到数据资产平台中。
上图绿色和蓝色分别表示:
- 蓝色:对不同血缘接入过程的逻辑一致,可抽象出来并复用。
- 绿色:不同血缘的实现情况不一样。例如,某一个平台为拉取数据,另外一个平台通过其他方式获取数据,导致三个部分不一样,因此我们抽取特殊部分,复用共同部分。除此之外,我们还提供通用 SDK,串联整个血缘接入流程,使得接入新的血缘时,只需要实现绿色组件。
目前,字节跳动内部业务已经可以使用 SDK 轻松接入血缘。
数据血缘质量-覆盖率
当血缘发展到一定阶段,业务方不止关心血缘覆盖情况、支持情况,还关心血缘数据质量情况。因此,第三版本透出血缘质量相关指标——覆盖率和准确率。
覆盖率:血缘覆盖的数据资产数占关注的资产数量占比。
关注的数据资产一般指,有生产任务或有生产行为的资产。上图虚线圆圈,如 Table 9,用户创建该表后没有生产行为,因此也不会产生血缘,在计算中将被剔除掉。上图实线圆圈,表示有生产行为或有任务读取,则被认为是关注的资产。关注的数据资产被血缘覆盖的占比,即覆盖率。
以上图为例,在 10 张表中,由于有任务与 Table 1 ~ 8 关联,因此判定有血缘。 Table 10,它与 Task-D 之间的连线是虚线,表示本来它应该有血缘,但是实际上血缘任务没把这个血缘关系解析出来,那么我们就认为这个 Table 10 是没有被血缘覆盖的。整体上被血缘覆盖的资产就是表 1 ~ 8。除了 Table 9 之外,其他的都是关注的资产,那么血缘覆盖的资产占比就是 8/9。也就是图上蓝色的这第 8 个除以蓝色的 8 个加上 Table 10,就是 9 个,所以这个覆盖率就是 88%。
数据血缘质量-准确率
覆盖血缘不一定是正确的,所以我们还定义了准确率指标,即血缘准确的任务数/同类型的任务数。
举个例子,假设任务 c 的血缘应该是 Table 5、Table6 生成 Table 7,但实际上被遗漏,没有被解析(虚线表示),导致任务 c 的血缘不准确。也存在其他情况缺失或多余情况,导致血缘不准确。
在上图中,同类型任务包含 4 个,即 a、b、c、d。那么,准确的血缘解析只有 a、b,因此准确率占比为 2/4 = 50%。
在火山引擎 DataLeap 中,由于血缘来源是任务,因此我们以任务的视角来看待血缘准确率。
血缘质量-字节现状
在覆盖率部分,目前 Hive 和 ClickHouse 元数据覆盖度较高,分别达到 98%、96%。对于实时元数据,如 Kafka ,相关 Topic 覆盖 70%,其他元数据则稍低。
在准确率部分,我们区分任务类型做准确性解析。如 DTS 数据集成任务达到 99%以上,Hive SQL 任务、 Flink SQL 任务是 97%、81% 左右。
血缘架构对比
上图为三个版本对比情况:
- 血缘的消费方式:第一版只支持 API 的方式,用户需要在数据资产平台上查看血缘信息;第二版支持离线数仓,让用户可以全量分析血缘;第三版支持消息队列,使用户可以获取血缘增量的变化。
- 增量更新:第三版开始支持增量更新。
- 血缘任务:第二个版本开始支持任务血缘,第三个版本支持数据质量。
- 元数据存储统一:第三版进行了元数据架构升级,使得元数据和血缘存储在同一个地方。
- 新血缘接入耗时:前两个版本大概需要花费 7-10 天左右。第三版本引入标准化,外部业务方或字节内部用标准化流程,实现 3、4 天左右完成开发、测试、上线。
未来展望
第一,持续对架构和流程进行精简。目前,血缘任务分为离线和实时两部分,但没有完全统一。在插件化、横向扩展等方面也需要加强。
第二,生态化支持。目前支持公司内部的元数据,未来计划拓展对开源或外部元数据的支持。在血缘标准化方面,提供一站式数据血缘能力,作为基础能力平台为业务方提供服务。
第三,提升数据质量。除了血缘数量,还需要持续提升质量。同时由于数据链路复杂,导致链路问题排查异常困难,未来我们也会支持快速诊断。
最后,支持智能化场景。结合元数仓等数据,提供包含关键链路梳理在内的智能化能力。目前,当业务方发现数据有问题之后,主要通过按照血缘数据一个一个排查方式解决,导致效率低下。未来,我们将考虑透出血缘关键链路,提升排查效率。
以上介绍的数据血缘能力和实践,目前大部分已通过火山引擎 DataLeap 对外提供服务。
点击跳转 大数据研发治理套件 DataLeap 了解更多
以上是关于火山引擎DataLeap:3步打造“指标管理”体系,幸福里数据中心是这么做的的主要内容,如果未能解决你的问题,请参考以下文章
火山引擎DataLeap联合DataFun发布《数据治理知识地图》
火山引擎DataLeap:3个关键步骤,复制字节跳动一站式数据治理经验
火山引擎DataLeap数据调度实例的 DAG 优化方案 :功能设计