Spark之SQL解析(源码阅读十)

  如何能更好的运用与监控sparkSQL?或许咱们改更深层次的了解它深层次的原理是什么。以前总结的已经写了传统数据库与Spark的sql解析之间的差异。那么咱们下来直切主题~sql

  现在的Spark已经支持多种多样的数据源的查询与加载,兼容了Hive,可用JDBC的方式或者ODBC来链接Spark SQL。下图为官网给出的架构.那么sparkSql呢能够重用Hive自己提供的元数据仓库(MetaStore)HiveQL、以及用户自定义函数(UDF)序列化反序列化的工具(SerDes).数据库

  下来咱们来细化SparkContext,大的流程是这样的:缓存

  一、SQL语句通过SqlParser解析成Unresolved LogicalPlan;架构

  二、使用analyzer结合数据字典(catalog)进行绑定,生成Resolved LogicalPlan;app

  三、使用optimizerResolved LogicalPlan进行优化,生成Optimized LogicalPlan;函数

  四、使用SparkPlanLogicalPlan转换成PhysiclPlan;工具

  五、使用prepareForExceptionPhysicalPlan转换成可执行物理计划。源码分析

  六、使用execute()执行可执行物理计划,生成DataFrame.优化

  这些解析的过程,咱们均可以经过监控页面观察的到。spa

  下来咱们先从第一个Catalog开始,什么是Catalog?它是一个字典表,用于注册表,对标缓存后便于查询,源码以下:

  

  这个类呢,是个特质,定义了一些tableExistes:判断表是否存在啊,registerTable:注册表啊、unregisterAllTables:清除全部已经注册的表啊等等。在建立时,new的是SimpleCatalog实现类,这个类实现了Catalog中的全部接口,将表名logicalPlan一块儿放入table缓存,曾经的版本中呢,使用的是mutable.HashMap[String,LogicalPlan]。如今声明的是ConcurrentHashMap[String,LogicalPlan]

  而后呢,咱们来看一下词法解析器Parser的实现。在原先的版本中,调用sql方法,返回的是SchemaRDD,如今的返回类型为DataFrame:

  

  你会发现,调用了parseSql,在解析完后返回的是一个物理计划。

  

  咱们再深刻parse方法,发现这里隐式调用了apply方法

  

  下来咱们看一下,它的建表语句解析,你会发现其实它是解析了物理计划,而后模式匹配来建立表:

  

  最后调用了RefreshTable中的run方法:

  

  那么建立完表了,下来开始痛苦的sql解析。。。上传说中的操做符函数与解析的全部sql函数!

  

   

  一望拉不到底。。。这个Keyword实际上是对sql语句进行了解析:

  

  而后拿一个select的sql语法解析为例,本质就是将sql语句的条件进行了匹配过滤筛选

  

  一个select的步骤包括,获取DISTINCT语句投影字段projection表relationswhere后的表达式group by后的表达式hiving后的表达式排序字段orderingLimit后的表达式。随之就进行匹配封装操做RDD,Filter、Aggregate、Project、Distinct、sort、Limit,最终造成一颗LogicalPlan的Tree.

  那么join操做,也包含了左外链接、全外链接、笛卡尔积等。

  

  好的,既然sql的执行计划解析完了,下来该对解析后的执行计划进行优化,刚才的解析过程将sql解析为了一个Unresolved LogicalPlan的一棵树。下来Analyzeroptimizer将会对LogicalPlan的这棵树加入各类分析和优化操做,好比列剪枝谓词下压啊。

  AnalyzerUnresolved LogicalPlan数据字典(catalog)进行绑定,生成resolved LogicalPlan.而后呢OptimizerResolved LogicalPlan进行优化,生成Optimized LogicalPlan.

  

  这里的useCachedData方法实际是用于将LogicalPlan的树段替换为缓存中的。具体过滤优化看不懂啊TAT 算了。。第一遍源码,讲究先全通一下吧。

  下来,一系列的解析啊、分析啊、优化啊操做事后,由于生成的逻辑执行计划没法被当作通常的job来处理,因此为了可以将逻辑执行计划按照其余job同样对待,须要将逻辑执行计划变为物理执行计划。

  

  以下图,你注意哦,配置文件中shufflePartition的个数就是从这里传进来的。

  

  

  这里面真正牛逼变态的是BasicOperators。它对最经常使用的SQL关键字都作了处理,每一个处理的分支,都会调用planLater方法,planLater方法给child节点的LogicalPlan应用sparkPlanner,因而就差造成了迭代处理的过程。最终实现将整颗LogicalPlan树使用SparkPlanner来完成转换。最终执行物理计划。

  

  

参考文献:《深刻理解Spark:核心思想与源码分析》

相关文章
相关标签/搜索