Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spark Sql 源码剖析(三):Analyzer

Spark Sql 源码剖析(三):Analyzer

作者头像
codingforfun
发布于 2018-08-24 08:05:55
发布于 2018-08-24 08:05:55
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

当一条 sql 语句被 SparkSqlParser 解析为一个 unresolved logicalPlan 后,接下来就会使用 Analyzer 进行 resolve。所谓的 resolve 也就是在未解析的 db、table、function、partition 等对应的 node 上应用一条条 Rule(规则)来替换为新的 node,应用 Rule 的过程中往往会访问 catalog 来获取相应的信息。

先来看看在解析过程中涉及到的几个主要类,以便为之后的详细分析做好铺垫。

一、主要类

上图(省略了诸多成员,方法)列举了解析一个 unresolved logicalPlan 时涉及的主要类及其之间的关系,其中 Analyzer 是解析的入口,其定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Analyzer(
    catalog: SessionCatalog,
    conf: SQLConf,
    maxIterations: Int)
  extends RuleExecutor[LogicalPlan] with CheckAnalysis

先来看看几个主要的相关的类

1.1、SessionCatalog

SparkSession 使用的 catalog,是 spark 与底层 megastore(比如 Hive Metastore)的桥梁,并管理着 SparkSession 的临时表、view 以及函数。由于会有并发访问,该类是线程安全的。 如上图中该类的构造函数,该类借助 ExternalCatalog、GlobalTempViewManager、FunctionRegistry、FunctionResourceLoader 等类型的成员实现对 db、table、partition、function 的 CURD 等功能

1.1.1、ExternalCatalog

catalog 接口,包含 functions、partitions、tables 和 databases。仅适用于非临时的项目,线程安全。这是一个用来与外部系统交互的 external catalog(比如与 Hive Megastore 交互的实现是 HiveExternalCatalog,你也可以实现自己的 meta store 及相应的 ExternalCatalog)。当 database 不存在的时候,要抛出 NoSuchDatabaseException。主要包含以下几类方法:

  • database 相关:checkExists、create、alter、list、drop、alter、use database
  • table 相关:checkExists、create、alter、list、drop、alter schema、rename
  • partition 相关:load(加载数据到一个 partition)、load 动态分区、create、drop、rename、alter、get、list
  • function 相关:create、drop、alter、rename、checkExists、list
1.1.2、GlobalTempViewManager

一个线程安全的全局的 temp views 的 manager,提供对其原子的操作,比如 create、update、remove 等。注意,view 的名字是大小写敏感的。其包含对于 temp view 的方法:

  • get
  • create
  • update
  • remove
  • rename
  • list
  • clear
1.1.3、FunctionRegistry

Analyzer 用来查找 UDF 的 catalog,线程安全并且对 db name 大小写敏感。包含 function 相关的方法:

  • register
  • create or replace
  • look up
  • list
  • drop
  • checkExists
  • clear
1.1.4、FunctionResourceLoader

用来加载一个函数要使用的资源

1.2、RuleExecutor

定义了一个 rules 执行框架,即怎么把一批批规则应用在一个 plan 上得到一个新的 plan。具体是怎么做的,会在下面详细展开。

1.3、SQLConf

用来 get、set SQL 相关的配置、参数。其伴生 object 包含了 spark sql 的所有参数及其类型、说明、默认值。而 class SQLConf 提供了这些参数、配置的 getter、setter 方法。

1.4、CheckAnalysis

用于对 plan 做一些解析,如果解析失败则抛出用户层面的错误

二、如何解析

整个解析过程就是 Analyzer 通过继承或者包含实例的方式将这些类串起来,去 catalog 中查询信息并应用一系列规则来将一个 unresolved logicalplan 最终转变为一个新的 resolved plan 的过程。

2.1、规则是如何执行的?

2.1.1、Rule

在说明规则是如何执行之前,先说明什么是规则?规则均继承了 abstract class Rule,包含了一个 name 方法及 def apply(plan: TreeType): TreeType 方法,调用 apply 方法将一个 plan 转换成一个新的 plan,这个新的 plan 往往与原来的 plan 有一些不同,也有可能与执行规则前相同。

2.1.2、RuleExecutor

要把一个 unresolved logicalPlan 解析为一个 resolved logicalPlan,需要执行大量规则。那么,这么多规则是如何组织的?执行顺序是怎么样的?这些问题都能在 RuleExecutor 类中找到答案。

2.1.2.1、Batch

类 RuleExecutor 看名字就知道是用来 execute rule 的。在其内部定义了一个 Batch 类,用来表示 a batch of rules,即一组同类的不定长规则:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
case class Batch(name: String, 
                strategy: Strategy, 
                rules: Rule[TreeType]*)

其中,strategy: Strategy 即规则的执行策略,表示 Batch 最大执行次数。 如果执行了 maxIterations 次之前达到收敛点(在这里是执行规则后 plan 没有变化),也将停止,不再继续执行 Batch。而每个 Batch 的 maxIterations 都是经验值。

RuleExecutor 包含了一个 protected def batches: Seq[Batch] 方法,用来获取一系列 Batch,这些 Batch 都会在 execute 中执行。所有继承 RuleExecutor(Analyzer 和 Optimizer)都必须实现该方法,即提供自己的 Seq[Batch]。如果需要新增规则,只需要新增 Batch 或者再某个 Batch 中新增规则即可。整体的框架不用动。

2.1.2.2、RuleExecutor#execute

让我们来看看 Batch 和 rule 具体是怎么执行的,即 RuleExecutor#execute(plan: TreeType): TreeType 的逻辑:

有几个关键点:

  • Batch 都是连续执行的
  • Batch 中的 rules 也是连续执行的
  • 当 Batch 执行的次数达到其规定的最大执行次数或执行该 Batch 并未修改 plan,则不再继续运行该 batch

三、Analyzer 的 Seq[Batch]

Analyzer 的 Seq[Batch] 如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
lazy val batches: Seq[Batch] = Seq(
    Batch("Hints", fixedPoint,
      new ResolveHints.ResolveBroadcastHints(conf),
      ResolveHints.RemoveAllHints),
    Batch("Simple Sanity Check", Once,
      LookupFunctions),
    Batch("Substitution", fixedPoint,
      CTESubstitution,
      WindowsSubstitution,
      EliminateUnions,
      new SubstituteUnresolvedOrdinals(conf)),
    Batch("Resolution", fixedPoint,
      ResolveTableValuedFunctions ::
      ResolveRelations ::
      ResolveReferences ::
      ResolveCreateNamedStruct ::
      ResolveDeserializer ::
      ResolveNewInstance ::
      ResolveUpCast ::
      ResolveGroupingAnalytics ::
      ResolvePivot ::
      ResolveOrdinalInOrderByAndGroupBy ::
      ResolveAggAliasInGroupBy ::
      ResolveMissingReferences ::
      ExtractGenerator ::
      ResolveGenerate ::
      ResolveFunctions ::
      ResolveAliases ::
      ResolveSubquery ::
      ResolveSubqueryColumnAliases ::
      ResolveWindowOrder ::
      ResolveWindowFrame ::
      ResolveNaturalAndUsingJoin ::
      ExtractWindowExpressions ::
      GlobalAggregates ::
      ResolveAggregateFunctions ::
      TimeWindowing ::
      ResolveInlineTables(conf) ::
      ResolveTimeZone(conf) ::
      TypeCoercion.typeCoercionRules(conf) ++
      extendedResolutionRules : _*),
    Batch("Post-Hoc Resolution", Once, postHocResolutionRules: _*),
    Batch("View", Once,
      AliasViewChild(conf)),
    Batch("Nondeterministic", Once,
      PullOutNondeterministic),
    Batch("UDF", Once,
      HandleNullInputsForUDF),
    Batch("FixNullability", Once,
      FixNullability),
    Batch("Subquery", Once,
      UpdateOuterReferences),
    Batch("Cleanup", fixedPoint,
      CleanupAliases)
  )
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.05.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[Spark SQL] 源码解析之Analyzer
Analyzer模块将Unresolved LogicalPlan结合元数据catalog进行绑定,最终转化为Resolved LogicalPlan。跟着代码看流程:
UFO
2018/08/29
1.1K0
[Spark SQL] 源码解析之Optimizer
optimizer 以及之后的模块都只会在触发了action操作后才会执行。优化器是用来将Resolved LogicalPlan转化为optimized LogicalPlan的。
UFO
2018/08/29
1.1K0
Spark SQL 整体介绍
sparksession rdd sparkcontext sparksql sqlcontent dstream streammingcontext hivesql hivecontext
Freedom123
2024/03/29
830
Spark SQL 整体介绍
spark sql解析过程中对tree的遍历(源码详解)
Parsed Logical Plan, Analyzed Logical Plan, Optimized Logical Plan, Physical Plan
数据仓库践行者
2020/10/29
1.5K0
spark sql解析过程中对tree的遍历(源码详解)
Spark sql规则执行器RuleExecutor(源码解析)
Spark sql通过Analyzer中 定义的rule把Parsed Logical Plan解析成 Analyzed Logical Plan;通过Optimizer定义的rule把 Analyzed Logical Plan 优化成 Optimized Logical Plan 。
数据仓库践行者
2020/10/29
1.5K0
Spark sql规则执行器RuleExecutor(源码解析)
Spark源码系列(九)Spark SQL初体验之解析过程详解
好久没更新博客了,之前学了一些R语言和机器学习的内容,做了一些笔记,之后也会放到博客上面来给大家共享。一个月前就打算更新Spark Sql的内容了,因为一些别的事情耽误了,今天就简单写点,Spark1.2马上就要出来了,不知道变动会不会很大,据说添加了很多的新功能呢,期待中... 首先声明一下这个版本的代码是1.1的,之前讲的都是1.0的。 Spark支持两种模式,一种是在spark里面直接写sql,可以通过sql来查询对象,类似.net的LINQ一样,另外一种支持hive的HQL。不管是哪种方式,下面提到
岑玉海
2018/02/28
1.8K0
Spark源码系列(九)Spark SQL初体验之解析过程详解
Spark Sql 源码剖析(二): TreeNode
使用 object CurrentOrigin 为 TreeNodes 提供一个可以查找上下文的地方,比如当前正在解析哪行 code。
codingforfun
2018/08/24
9660
TiSpark 原理之下推丨TiDB 工具分享
TiSpark 是 PingCAP 为解决用户复杂 OLAP 需求而推出的产品。它通过 Spark 提供的拓展机制与内置的 TiKV Client Java,在 Spark 之上直连 TiKV 进行读写,具有事务性读取、事务性写入与删除等能力。其中在事务性读取中基于 Spark Extension 实现了下推(详情可见 TiSpark 用户指南)。
PingCAP
2022/08/11
4430
Spark SQL / Catalyst 内部原理 与 RBO
从上图可见,无论是直接使用 SQL 语句还是使用 DataFrame,都会经过如下步骤转换成 DAG 对 RDD 的操作
Jason Guo
2018/09/11
1.4K0
一文了解函数式查询优化器Spark SQL Catalyst
记录一下个人对sparkSql的catalyst这个函数式的可扩展的查询优化器的理解,目录如下:
大数据真好玩
2020/06/03
3K0
在所有Spark模块中,我愿称SparkSQL为最强!
我们之前已经学习过了《我们在学习Spark的时候,到底在学习什么?》,这其中有一个关于SQL的重要模块:SparkSQL。
王知无-import_bigdata
2021/07/30
1.8K0
Spark Sql 源码剖析(一):sql 执行的主要流程
之前写过不少 Spark Core、Spark Streaming 相关的文章,但使用更广泛的 Spark Sql 倒是极少,恰好最近工作中使用到了,便开始研读相关的源码以及写相应的文章,这篇便作为 Spark Sql 系列文章的第一篇。
codingforfun
2018/08/24
2.1K0
Spark Sql 源码剖析(一):sql 执行的主要流程
[Spark SQL] 主要执行流程
SparkSql的第一件事就是把SQLText解析成语法树,这棵树包含了很多节点对象,节点可以有特定的数据类型,同时可以有0个或者多个子节点,节点在SparkSQL中的表现形式为TreeNode对象。举个实际的例子:
UFO
2018/08/29
1.8K0
[Spark SQL] 源码解析之Parser
Parser就是将SQL字符串切分成一个个Token,再根据一定语义规则解析为一棵语法树。我们写的sql语句只是一个字符串而已,首先需要将其通过词法解析和语法解析生成语法树,Spark1.x版本使用的是scala原生的parser语法解析器,从2.x后改用的是第三方语法解析工具ANTLR4, 在性能上有了较大的提升。
UFO
2018/08/29
2.5K0
SparkSql源码成神之路
快来加入我的源码学习社群吧,在社群的长期陪伴下,解决你在学习路上遇到的点点滴滴的问题~~
数据仓库践行者
2022/11/24
1K0
SparkSql源码成神之路
SparkSQL内核解析之逻辑计划
LogicalPlan的父类QueryPlan主要分为六个模块: – 输入输出 涉及QueryPlan内属性相关的输入输出 – 基本属性 QueryPlan内的基本属性 – 字符串 主要用于打印QueryPlan的树形结构信息 – 规范化 类似Expression中的规范化 – 表达式操作 – 约束 本质上也是数据过滤条件的一种,同样是表达式类型。通过显式的过滤条件推导约束
王知无-import_bigdata
2020/06/04
2.2K0
初识 Spark SQL | 20张图详解 Spark SQL 运行原理及数据抽象
不管是做平台的,还是做应用的,都免不了跟 SQL 打交道。一句“SQL Boy”,虽然是大家的自嘲,但也能说明大数据工程师们跟 SQL 的关系之紧密。
数人之道
2022/03/28
11K0
初识 Spark SQL | 20张图详解 Spark SQL 运行原理及数据抽象
sparksql源码系列 | 生成resolved logical plan的解析规则整理
之前有分享过一篇笔记:Spark sql规则执行器RuleExecutor(源码解析) 里面有提到Analyzer、Optimizer定义了一系列 rule。 其中Analyzer定义了从【未解析的逻辑执行计划】生成【解析后的逻辑执行计划】的一系列规则,这篇笔记整理了一下这些规则都哪些。 基于spark3.2 branch rule【规则】 batch【表示一组同类的规则】 strategy【迭代策略】 注释 OptimizeUpdateFields Substitution fixedPoint 此
数据仓库践行者
2022/04/18
3.7K0
sparksql源码系列 | 生成resolved logical plan的解析规则整理
Spark CBO统计元数据
Statistics 统计信息,参考:org.apache.spark.sql.catalyst.plans.logical.Statistics
Yiwenwu
2024/04/27
3461
Spark SQL | Spark,从入门到精通
欢迎阅读美图数据技术团队的「Spark,从入门到精通」系列文章,本系列文章将由浅入深为大家介绍 Spark,从框架入门到底层架构的实现,相信总有一种姿势适合你。
美图数据技术团队
2019/04/19
2K0
Spark SQL | Spark,从入门到精通
相关推荐
[Spark SQL] 源码解析之Analyzer
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验