大数据技术与架构点击右侧关注,大数据开发领域最强公众号!

暴走大数据点击右侧关注,暴走大数据!记录一下个人对sparkSql的catalyst这个函数式的可扩展的查询优化器的理解,目录如下:

0. Overview1. Catalyst工作流程2. Parser模块3. Analyzer模块4. Optimizer模块5. SparkPlanner模块6. Job UI7. Reference

Overview

Spark SQL的核心是Catalyst优化器,是以一种新颖的方式利用Scala的的模式匹配和quasiquotes机制来构建的可扩展查询优化器。sparkSql pipelinesparkSql的catalyst优化器是整个sparkSql pipeline的中间核心部分,其执行策略主要两方向,

  1. 基于规则优化/Rule Based Optimizer/RBO

  • nestedLoopsJoin,P,Q双表两个大循环, O(M*N)

  • sortMergeJoin是P,Q双表排序后互相游标

  • broadcastHashJoin,PQ双表中小表放入内存hash表,大表遍历O(1)方式取小表内容

  • 一种经验式、启发式优化思路

  • 对于核心优化算子join有点力不从心,如两张表执行join,到底使用broadcaseHashJoin还是sortMergeJoin,目前sparkSql是通过手工设定参数来确定的,如果一个表的数据量小于某个阈值(默认10M?)就使用broadcastHashJoin

基于代价优化/Cost Based Optimizer/CBO

  • 针对每个join评估当前两张表使用每种join策略的代价,根据代价估算确定一种代价最小的方案

  • 不同physical plans输入到代价模型(目前是统计),调整join顺序,减少中间shuffle数据集大小,达到最优输出


Catalyst工作流程

  • Parser,利用ANTLR将sparkSql字符串解析为抽象语法树AST,称为unresolved logical plan/ULP

  • Analyzer,借助于数据元数据catalog将ULP解析为logical plan/LP

  • Optimizer,根据各种RBO,CBO优化策略得到optimized logical plan/OLP,主要是对Logical Plan进行剪枝,合并等操作,进而删除掉一些无用计算,或对一些计算的多个步骤进行合并

other

Optimizer是catalyst工作最后阶段了,后面生成physical plan以及执行,主要是由sparkSql来完成。

  • SparkPlanner

    • 优化后的逻辑执行计划OLP依然是逻辑的,并不能被spark系统理解,此时需要将OLP转换成physical plan

    • 从逻辑计划/OLP生成一个或多个物理执行计划,基于成本模型cost model从中选择一个

  • Code generation

    • 生成Java bytecode然后在每一台机器上执行,形成RDD graph/DAG


Parser模块

将sparkSql字符串切分成一个一个token,再根据一定语义规则解析为一个抽象语法树/AST。Parser模块目前基本都使用第三方类库ANTLR来实现,比如Hive,presto,sparkSql等。parser切词Spark 1.x版本使用的是Scala原生的Parser Combinator构建词法和语法分析器,而Spark 2.x版本使用的是第三方语法解析器工具ANTLR4。Spark2.x SQL语句的解析采用的是ANTLR4,ANTLR4根据语法文件SqlBase.g4自动解析生成两个Java类:词法解析器SqlBaseLexer和语法解析器SqlBaseParser。SqlBaseLexer和SqlBaseParser都是使用ANTLR4自动生成的Java类。使用这两个解析器将SQL字符串语句解析成了ANTLR4的ParseTree语法树结构。然后在parsePlan过程中,使用AstBuilder.scala将ParseTree转换成catalyst表达式逻辑计划LogicalPlan。


Analyzer模块

通过解析后ULP有了基本骨架,但是系统对表的字段信息是不知道的。如sum,select,join,where还有score,people都表示什么含义,此时需要基本的元数据信息schema catalog来表达这些token。最重要的元数据信息就是,

  • 表的schema信息,主要包括表的基本定义(表名、列名、数据类型)、表的数据格式(json、text、parquet、压缩格式等)、表的物理位置

  • 基本函数信息,主要是指类信息

Analyzer会再次遍历整个AST,对树上的每个节点进行数据类型绑定以及函数绑定,比如people词素会根据元数据表信息解析为包含age、id以及name三列的表,people.age会被解析为数据类型为int的变量,sum会被解析为特定的聚合函数,词义注入

//org.apache.spark.sql.catalyst.analysis.Analyzer.scala  lazy val batches: Seq[Batch] = Seq( //不同Batch代表不同的解析策略Batch("Substitution", fixedPoint,      CTESubstitution,      WindowsSubstitution,      EliminateUnions,new SubstituteUnresolvedOrdinals(conf)),Batch("Resolution", fixedPoint,      ResolveTableValuedFunctions ::      ResolveRelations ::  //通过catalog解析表或列基本数据类型,命名等信息      ResolveReferences :: //解析从子节点的操作生成的属性,一般是别名引起的,比如people.age      ResolveCreateNamedStruct ::      ResolveDeserializer ::      ResolveNewInstance ::      ResolveUpCast ::      ResolveGroupingAnalytics ::      ResolvePivot ::      ResolveOrdinalInOrderByAndGroupBy ::      ResolveMissingReferences ::      ExtractGenerator ::      ResolveGenerate ::      ResolveFunctions :: //解析基本函数,如max,min,agg      ResolveAliases ::      ResolveSubquery :: //解析AST中的字查询信息      ResolveWindowOrder ::      ResolveWindowFrame ::      ResolveNaturalAndUsingJoin ::      ExtractWindowExpressions ::      GlobalAggregates :: //解析全局的聚合函数,比如select sum(score) from table      ResolveAggregateFunctions ::      TimeWindowing ::      ResolveInlineTables ::      TypeCoercion.typeCoercionRules ++      extendedResolutionRules : _*),Batch("Nondeterministic", Once,      PullOutNondeterministic),Batch("UDF", Once,      HandleNullInputsForUDF),Batch("FixNullability", Once,      FixNullability),Batch("Cleanup", fixedPoint,      CleanupAliases))

Optimizer模块

Optimizer是catalyst的核心,分为RBO和CBO两种。
RBO的优化策略就是对语法树进行一次遍历,模式匹配能够满足特定规则的节点,再进行相应的等价转换,即将一棵树等价地转换为另一棵树。SQL中经典的常见优化规则有,

  • 谓词下推(predicate pushdown)

  • 常量累加(constant folding)

  • 列值裁剪(column pruning)

  • Limits合并(combine limits)

由下往上走,从join后再filter优化为filter再join

从`100+80`优化为`180`,避免每一条record都需要执行一次`100+80`的操作

剪裁不需要的字段,特别是嵌套里面的不需要字段。如只需people.age,不需要people.address,那么可以将address字段丢弃

//@see http://blog.csdn.net/oopsoom/article/details/38121259//org.apache.spark.sql.catalyst.optimizer.Optimizer.scala  def batches: Seq[Batch] = {// Technically some of the rules in Finish Analysis are not optimizer rules and belong more// in the analyzer, because they are needed for correctness (e.g. ComputeCurrentTime).// However, because we also use the analyzer to canonicalized queries (for view definition),// we do not eliminate subqueries or compute current time in the analyzer.Batch("Finish Analysis", Once,      EliminateSubqueryAliases,      ReplaceExpressions,      ComputeCurrentTime,GetCurrentDatabase(sessionCatalog),      RewriteDistinctAggregates) :://// Optimizer rules start here//// - Do the first call of CombineUnions before starting the major Optimizer rules,//   since it can reduce the number of iteration and the other rules could add/move//   extra operators between two adjacent Union operators.// - Call CombineUnions again in Batch("Operator Optimizations"),//   since the other rules might make two separate Unions operators adjacent.Batch("Union", Once,      CombineUnions) ::Batch("Subquery", Once,      OptimizeSubqueries) ::Batch("Replace Operators", fixedPoint,      ReplaceIntersectWithSemiJoin,      ReplaceExceptWithAntiJoin,      ReplaceDistinctWithAggregate) ::Batch("Aggregate", fixedPoint,      RemoveLiteralFromGroupExpressions,      RemoveRepetitionFromGroupExpressions) ::Batch("Operator Optimizations", fixedPoint,// Operator push down      PushProjectionThroughUnion,      ReorderJoin,      EliminateOuterJoin,      PushPredicateThroughJoin, //谓词下推之一      PushDownPredicate, //谓词下推之一      LimitPushDown,      ColumnPruning, //列值剪裁,常用于聚合操作,join左右孩子操作,合并相邻project列      InferFiltersFromConstraints,// Operator combine      CollapseRepartition,      CollapseProject,      CollapseWindow,      CombineFilters, //谓词下推之一,合并两个相邻的Filter。合并2个节点,就可以减少树的深度从而减少重复执行过滤的代价      CombineLimits, //合并Limits      CombineUnions,// Constant folding and strength reduction      NullPropagation,      FoldablePropagation,OptimizeIn(conf),      ConstantFolding, //常量累加之一      ReorderAssociativeOperator,      LikeSimplification,      BooleanSimplification, //常量累加之一,布尔表达式的提前短路      SimplifyConditionals,      RemoveDispensableExpressions,      SimplifyBinaryComparison,      PruneFilters,      EliminateSorts,      SimplifyCasts,      SimplifyCaseConversionExpressions,      RewriteCorrelatedScalarSubquery,      EliminateSerialization,      RemoveRedundantAliases,      RemoveRedundantProject) ::Batch("Check Cartesian Products", Once,CheckCartesianProducts(conf)) ::Batch("Decimal Optimizations", fixedPoint,      DecimalAggregates) ::Batch("Typed Filter Optimization", fixedPoint,      CombineTypedFilters) ::Batch("LocalRelation", fixedPoint,      ConvertToLocalRelation,      PropagateEmptyRelation) ::Batch("OptimizeCodegen", Once,OptimizeCodegen(conf)) ::Batch("RewriteSubquery", Once,      RewritePredicateSubquery,      CollapseProject) :: Nil}

SparkPlanner模块

至此,OLP已经得到了比较完善的优化,然而此时OLP依然没有办法真正执行,它们只是逻辑上可行,实际上spark并不知道如何去执行这个OLP。

  • 比如join只是一个抽象概念,代表两个表根据相同的id进行合并,然而具体怎么实现这个合并,逻辑执行计划并没有说明

optimized logical plan -> physical plan

此时就需要将左边的OLP转换为physical plan物理执行计划,将逻辑上可行的执行计划变为spark可以真正执行的计划。

  • 比如join算子,spark根据不同场景为该算子制定了不同的算法策略,有broadcastHashJoin、shuffleHashJoin以及sortMergeJoin,物理执行计划实际上就是在这些具体实现中挑选一个耗时最小的算法实现,这个过程涉及到cost model/CBO

CBO off

CBO on

CBO中常见的优化是join换位,以便尽量减少中间shuffle数据集大小,达到最优输出。

Job UI

  • WholeStageCodegen,将多个operators合并成一个java函数,从而提高执行速度

  • Project,投影/只取所需列

  • Exchange,stage间隔,产生了shuffle

欢迎点赞+收藏欢迎转发至朋友圈

递归下降语法分析器的构建_一文了解函数式查询优化器Spark SQL Catalyst相关推荐

  1. 《编译原理》实验报告——递归下降语法分析器的构建

    一.实验要求 运用递归下降法,针对给定的上下文无关文法,给出实验方案.预估实验中可能出现的问题. 二.实验方案 1.构造LL(1),通过设计.编制.调试递归下降语法分析程序,对输入的符号串进行分析匹配 ...

  2. 编译原理实验-递归下降语法分析器的构建

    实验目的: 针对给定的上下文无关文法,编制一个递归下降分析程序. 分析: 递归下降语法分析的前提是保证LL(1)文法 递归下降的思路就是暴力dfs.对每个程序直接不管三七二十一搜进去,只要能搜到就继续 ...

  3. 《编译原理》实验预习报告——递归下降语法分析器的构建

    一.实验目的 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析.本次实验的目的主要是加深对递归下降分析法的理解. 二.实验预习提示 1.递归下降分析法的功能 词法分析器的功能是利用 ...

  4. 递归下降文法C语言实验报告,递归下降语法分析器实验报告.doc

    递归下降语法分析器实验报告 编译原理实验报告 题目: 递归下降语法分析器 学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 ...

  5. 编译原理 - 实验三 - 递归下降语法分析器的调试及扩展

    一. 语法分析介绍 语法分析是编译过程的核心部分,它的主要任务是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成做准备.执行语法分析任 ...

  6. 编写递归下降语法分析器_面试BAT必问的JVM,今天我们来说一说它类加载器的底层原理...

    类加载器的关系 类加载器的分类 JVM支持两种类加载器,一种为引导类加载器(Bootstrap ClassLoader),另外一种是自定义类加载器(User Defined ClassLoader) ...

  7. 编写递归下降语法分析器_Python3知识点流程控制、迭代器、生成器快速入门

    流程控制 if 控制 if 表达式1: 语句if 表达式2: 语句elif 表达式3: 语句else: 语句elif 表达式4: 语句else: 语句 1.每个条件后面要使用冒号 :,表示接下来是满足 ...

  8. SNL文法的递归下降语法分析器

    得到token序列后,我们就可以采用递归下降法对其进行语法分析.如果没有语法错误,打印token序列,提示没有语法错误,否则,打印已经匹配的token,提示语法错误.(下面程序使用vs2013编译) ...

  9. 《编译原理》实验报告——基于YACC的TINY语法分析器的构建

    一.实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验方案 (1)设计基于LEX的TINY词法分析器 (2)设计基于YACC的TINY语法分析器 ( ...

最新文章

  1. wampserver搭建本地服务器
  2. 用Hibernate Tools生成Hibernate Mapping映射文件
  3. LeetCode每日一题 24. 两两交换链表中的节点
  4. Spring与Struts2整合的两种解决方案
  5. 使用openssl的md5库
  6. php登录注册脚本,PHP - 登录脚本
  7. [有限元] 四结点三角形单元和五结点三角形单元的形函数
  8. 结业考试笔记 2014中超联赛项目笔记 0327
  9. mysql mybatis 主键id_MyBatis+MySQL 返回插入的主键ID
  10. Nginx gzip参数详解及常见问题(已解决)
  11. 《啊哈!算法》第5章 图的遍历
  12. sysbench 0.5 oltp测试笔记
  13. 自主招生计算机网测,自主招生考试中,笔试和机试有什么区别?
  14. 一级造价工程师(安装)- 管理笔记
  15. TreeMap根据value排序遇到的问题及分析
  16. 数据库-内外连接及左右连接的区别
  17. javascript接口鸭式辨型法实现
  18. android 文件扫描MediaStore
  19. 中国首台超级计算机“天河一号,中国首台千万亿次超级计算机天河一号安装完毕...
  20. Centos Denyhosts 一键安装配置脚本

热门文章

  1. 如何用纯 CSS 创作一个文本淡入淡出的 loader 动画
  2. 纯CSS实现3D照片墙
  3. 小谈React、React Native、React Web
  4. html/css学习笔记(一)
  5. photoshop 切片工具进行切图
  6. Linux系统之TroubleShooting(启动故障排除)
  7. 4~20mA模拟输出(电流环)应用笔记(转)
  8. 字符搜索正则表达式语法详解
  9. pHp中文网零基础,零基础编程
  10. 灵格斯怎么屏幕取词_电脑包尺寸怎么选?手提的好还是双肩的好?比较推荐哪款电脑包?...