元数据之-血缘分析实战

3,637 阅读5分钟

引入

做过大数据或者接触过数仓的同学,相信都有听到过数据治理、血缘分析的专业术语。不知道大家有没有思考过以下几个问题:
1、什么是血缘分析?主要分析什么东西?
2、为什么要做血缘分析,主要是为了解决什么痛点?做出来之后有什么价值?如何衡量这些价值?
3、如何做血缘分析?
关于第1,2个问题是需要结合每个企业实际的情况来思考,当然分析其本质就是方便数据梳理。那么本篇主要侧重于第3个问题,通过工程+方法论的方式来为读者们揭开血缘分析功能的神秘面纱。

效果展示

关于如何做血缘分析,其实每个企业的做法都大差不差,主要差别在于实现的深度。例如:有的企业是直接引用现有的开源工具,有的企业是结合自身的产品进行自研,有的企业可能只做到表级别,有的企业做到字段级别。那么本篇将会为读者们提供一种表级别粒度的分析功能,并通过可视化的方式为大家展示,当然本篇文章是属于抛砖引玉,主要是给大家提供一种思路。先为读者们展示最终效果图:

执行底层

在数仓工作职责内,大部分都是SQL化,因此血缘分析大多数都是基于SQL解析来做。当然也有非SQL的场景,不过其思想和做法都是一样的,只是API层面的调用不同而已。本篇就以SparkSQL作为一种场景举例说明。
说到SparkSQL,那么不得不先来了解下其具体的底层流程(当然Hive的解析也是一样,同样要先熟悉其底层流程)。
如上图所示:
整体可以分为以下两个流程:
1、逻辑计划:提交sql,spark进行解析生成逻辑计划,然后进行规则绑定,优化
2、物理计划:spark将优化后的逻辑计划进行切分生成物理计划,然后进行提交,生成job任务
每个环节进行梳理的话,可以分为以下几个流程(当然这里也只是大概介绍一下,当大家有兴趣做这一块的时候可以深入研究):
1、当我们在client端提交一段sql后,spark会通过Antlr4进行词法、语法解析来校验SQl语法(当然这里会根据g4文件进行匹配)得到AST,生成未解析的逻辑计划Unresolved Logical Plan。此时的计划还不知道字段类型和表数据等信息
2、spark通过analyzer结合catalog对未解析的逻辑计划,进行一系列的规则绑定,应用数据信息,生成Resolved Logical Plan,此时的计划也是按照原来的节点原封不动进行绑定,并没有做任何的优化.
3、Spark中的Optimizer在保证数据结果正确的前提下,对解析后的逻辑计划进行优化,例如通常所提到的谓词下推、列裁剪、join优化、算子组合等多种优化手段会在该阶段使用,最后得到Optimized Logical Plan
4、当得到优化后的逻辑计划后,会通过Planner将各种策略应用到Logical Plan上,选择最优的物理计划进行提交执行。
注意:通过对上图sql流程的简单介绍,其中关于sparksql中的CBO,AE优化,相信读者们也有一个更清晰的理解。

源码分析

本篇选择用sparksql作为解析对象,其主要原因在于目前大多数企业在sparksql上的使用已经比较广泛且成熟,当然hive的解析也可以仿照本篇思想进行。那么结合上面的底层执行流程的理解,我们只需要解析到表依赖关系即可,所以只需要获取到Unresolved Logical Plan阶段的信息即可。那么问题来了,我们该从何处下手呢?这个时候我们可以先看下sparksql是如何做到的,那么不得不看下源码了。
首先我们知道提交sql的入口是通过SparkSession.sql方法进行执行的,那么就进入到该方法内查看。

其实你看到这一步的话,就已经可以了,直接调用parsePlan方法获取到Plan。不过我们这里再继续深入一下。
这里需要查看下有哪些实现类 如果你继续深入的话,会看到AbstractSqlParser.parse方法是具体解析sql生成AST的地方. 当然这也只是一个抽象类,那么我们最后会看到以下两个实现类。本篇是通过使用SparkSqlParser来实现sql解析.具体源码部分不在叙述,有兴趣的同学可以研究。

工程实现

在源码分析部分,大概引入了一下sparksql底层的解析入口。该篇作为举例,选择使用SparkSqlParser来对sparksql进行解析。当然读者们也可以使用CatalystSqlParser或者ASTBuilder直接进行解析,同时可以对比两者直接的区别。
该篇demo选用的技术主要为SparkSqlParser(spark3.X)+图数据库Neo4j。
主要实现的支持sql语法包括:
1、Create [temporary] table/view [AS] ....
2、Insert into/overwrite ....
3、CTE
sql解析伪代码示例如下图: Neo4j代码如下图:

注意:
1、关于Neo4j部分,大家有兴趣可以自行研究,本篇不做介绍
2、本篇仅是给读者们提供一种思路,具体实现可自行操作。授人以鱼不如授人以渔
3、关于选择Spark3.X作为解析工具,是相对于spark2.X,有部分解析语法和规则不够全面,例如[SPARK-30822][SQL]Remove semicolon at the end of a sql query。