Spark 性能调优实战
吴磊
前 FreeWheel 机器学习团队负责人
8808 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Spark 性能调优实战
15
15
1.0x
00:00/00:00
登录|注册

21 | Catalyst逻辑计划:你的SQL语句是怎么被优化的?(上)

你好,我是吴磊。
上一讲我们说,Spark SQL 已经取代 Spark Core 成为了新一代的内核优化引擎,所有 Spark 子框架都能共享 Spark SQL 带来的性能红利,所以在 Spark 历次发布的新版本中,Spark SQL 占比最大。因此,Spark SQL 的优化过程是我们必须要掌握的。
Spark SQL 端到端的完整优化流程主要包括两个阶段:Catalyst 优化器和 Tungsten。其中,Catalyst 优化器又包含逻辑优化和物理优化两个阶段。为了把开发者的查询优化到极致,整个优化过程的运作机制设计得都很精密,因此我会用三讲的时间带你详细探讨。
下图就是这个过程的完整图示,你可以先通过它对优化流程有一个整体的认知。然后随着我的讲解,逐渐去夯实其中的关键环节、重要步骤和核心知识点,在深入局部优化细节的同时,把握全局优化流程,做到既见树木、也见森林。
Spark SQL的优化过程
今天这一讲,我们先来说说 Catalyst 优化器逻辑优化阶段的工作原理。

案例:小 Q 变身记

我们先来看一个例子,例子来自电子商务场景,业务需求很简单:给定交易事实表 transactions 和用户维度表 users,统计不同用户的交易额,数据源以 Parquet 的格式存储在分布式文件系统。因此,我们要先用 Parquet API 读取源文件。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Spark SQL的优化过程主要包括Catalyst优化器和Tungsten两个阶段。Catalyst优化器通过逻辑优化和物理优化两个阶段,利用81条优化规则将查询优化到极致。其中,谓词下推、列剪裁和常量替换是三大优化范畴,通过这些优化规则,Catalyst能够将查询的执行性能大幅提升。文章详细解释了Catalyst如何将“Analyzed Logical Plan”转换为“Optimized Logical Plan”,通过TreeNode的转换过程展示了优化规则的作用。此外,文章还介绍了Cache Manager的优化作用,通过维护缓存信息,Cache Manager能够充分利用已有的缓存数据进行优化。整体而言,本文通过案例分析和图示,深入剖析了Spark SQL的优化流程,为读者提供了宝贵的技术知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Spark 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • kingcall
    问题1:开发阶段要有极客精神,尽量将优化实现在自己的代码里,而不是依赖框架,因为框架是一个普世的优化,还有就是如果我们根据业务特点进行了优化再加上框架本身带来的优化能给我们的程序带来一个更好的性能提升,也就是说上层自我优化和底层框架优化。 问题2:与偏函数对应的一个定义就是我们数学意义上的函数,一个输入自变量x对应一个输出因变量y,也就是y 可以表示成x 的一个特定的运算,并且这个运算关系是确定的,但是scala 中的偏函数它表示的是一种匹配关系,有点类似if else if ... else ,只有匹配上了才有对应的值,否则输出的就是默认值 Spark 之所以用偏函数,而不是普通函数来定义 Catalyst 的优化规则,是因为规则是预先定义的,不可能满足所有的情况,所以需要一个兜底,而这正好满足偏函数的特点。

    作者回复: Perfect x 2!标准答案了~ 💯 回答的非常好了,无可挑剔~

    2021-04-30
    3
    32
  • jerry guo
    1. 既然 Catalyst 在逻辑优化阶段有 81 条优化规则,我们还需要遵循“能省则省、能拖则拖”的开发原则吗?你能说说 Spark 为什么用偏函数,而不是普通函数来定义 Catalyst 的优化规则吗? 答:要。战略上用开发原则,战术上依赖Catalyst。 2.你能说说 Spark 为什么用偏函数,而不是普通函数来定义 Catalyst 的优化规则吗? 答:网上搜到一篇文章 "The pattern matching expression that is passed to transform is a partial function, meaning that it only needs to match to a subset of all possible input trees. Catalyst will tests which parts of a tree a given rule applies to, automatically skipping over and descending into subtrees that do not match. This ability means that rules only need to reason about the trees where a given optimization applies and not those that do not match. Thus, rules do not need to be modified as new types of operators are added to the system." 这段不是很懂,大概意思是因为偏函数没有包括所有的情况,所以正好,符合定义的rule就优化,不符合就不处理,这样子比较省事;另外由于一开始没有完全定义出全部的情况(可能也定义不出来),所以这也有一定的灵活性,再新加了operator之后,也不需要改rule了。望老师指点。 3. 另外我有个问题,RDBMS的SQL优化很早之前是基于Rule,后面变成了基于Cost。根据本篇的讲解,Catalyst和Tunsgen,都是基于Rule的,网上搜索了一下,Catalyst也可以基于cost。老师可以讲讲对CBO的看法吗?比如CBO如何和Catalyst,Tusgen一起工作?或者以后CBO会变成主流吗?

    作者回复: 第二题分析的很到位,就是你说的这么回事。偏函数的特性,刚好符合Spark SQL优化规则的特点,也就是: 1. 不完备 2. 保持扩展的灵活性 问题三是个超级好的问题,其实我一直想找机会说说。在传统的DBMS里,CBO是主流,RBO是辅助性的。原因其实很简单,RBO毕竟是出于启发式的,都是一些“经验主义”,CBO才是真正“尊重”事实、尊重运行时的优化策略。在传统DBMS里面,CBO是非常成熟的技术了,已经沿用很多很多年了。 然而,Spark SQL的CBO相对就比较鸡肋了,原因其实我在第24讲会详细展开,提前剧透一下,就是Spark SQL的CBO有三个非常大的痛点:窄、慢、静 窄:窄指的是适用面太窄,CBO仅支持注册到Hive Metastore的数据表,但在大量的应用场景中,数据源往往是存储在分布式文件系统的各类文件,如Parquet、ORC、CSV等等。 慢:慢指的是统计信息的搜集效率比较低。对于注册到Hive Metastore的数据表,开发者需要调用ANALYZE TABLE COMPUTE STATISTICS语句收集统计信息,而各类信息的收集会消耗大量时间。 静:静指的是静态优化,这一点与RBO一样。CBO结合各类统计信息制定执行计划,一旦执行计划交付运行,CBO的使命就算完成了。这一点和传统DBMS很不同,传统DBMS的CBO是动态的,可以在运行时做适当调整。 不仅如此,目前Spark SQL的CBO,还仅仅支持Join策略,换句话说,与Join无关的查询,CBO使不上劲。 因此,综上,CBO虽然是个非常吸引人的东西,但是Spark SQL的CBO很鸡肋,当然这有很多原因,比如CBO本身的限制,社区对于Spark SQL优化方向的考虑,等等。其实AQE的推出,就表示Spark社区已经做出了选择。就我个人观察(仅代表个人观点哈),CBO的地位和角色可能会越来越尴尬,用武之地可能会越来越小,聊胜于无。当然,再次重申,这仅仅是我个人的观点哈~ 另外,这两个问题kingcall同学回答的比较好,可以参考他的答案哈~

    2021-04-30
    3
    8
  • mini希
    老师好,针对列剪裁是否只有列式的存储才能享受到扫描的优化效果,行存还是会扫描整行所有字段?

    作者回复: 对,你说的没错,确实只有列存才能从列剪裁受益,行存不行。

    2021-05-07
    4
  • 老师,执行计划中的project是什么意思啊,大概知道是和映射的关系,可不可以理解成相当于action算子一样

    作者回复: Project是投影的意思,实际上对应的就是你SQL或是DataFrame中的select语句,也就是说,在众多的数据列中,你要“投影”出哪些列,说白了,就是选出哪些列。 Project也会,Select也好,本身都不是算子哈,不管是SQL查询,还是DSL查询,都需要show、count、save等action算子来触发计算。

    2021-05-08
    3
  • 对方正在输入。。。
    老师的课,我是越看越爽,看完就有一种“老子天下无敌了”的感觉,哈哈哈哈哈

    作者回复: 哈哈哈,喜欢就好~ 兄弟五一节快乐~

    2021-05-01
    2
  • 农夫三拳
    老师 想问个问题,这个缓存是根据 查询树或者查询树的一部分作为key,进行缓存,匹配到了 就替换当前节点或者整棵树。 请问下 这个缓存是针对哪个阶段的查询树呢?是 解析,优化前,优化后,还是物理计划阶段? 我个人理解是优化后阶段。

    作者回复: 好问题~ 就Spark SQL目前的实现来看,它是在Analyzed Logical Plan之上做的这一步优化,也就是你说的“优化前”阶段。

    2021-08-12
    2
    1
  • 猿鸽君
    请问老师知道sparksql有时在执行insert overwrite hive table(静态分区)特别慢的原因吗?我翻了内外网都只给出了解决方案,却没有原因……

    作者回复: 老弟可以提供更详细的信息吗?比如具体的SQL语句,Spark和Hive的版本号,不同的Hive版本之间的差异还是挺大的

    2021-08-02
    3
    1
  • 西南偏北
    偏函数只针对部分输入来输出结果,而每个函数对应的优化规则也是有限的,再搭配模式匹配,很完美的应用场景哈哈

    作者回复: 对,没错,完美契合!老弟这进度赶得飞起啊~ 都追到21讲了~ 赞👍

    2021-05-05
    1
  • sky_sql
    老师好,RDD api有点类似MR编程,Spark SQL有点类似hive,过程都包括使用 Antlr 实现 SQL 的词法和语法解析,后面也有Schema 信息验证,优化环节谓词下推、列剪裁等?

    作者回复: 对,构建语法树、Schema验证、谓词下推、列剪裁,这些其实是绝大多数的数仓都有的优化策略。 实际上,相比传统DBMS,Spark SQL的优化流程算是简化版的了,比如传统DBMS还会有Query Re-writer、CBO(基于成本的优化)等等。

    2021-05-01
    1
  • Marco
    spark只用启发式的规则优化吗,有没有基于成本模型的优化?

    作者回复: 有的,CBO,不过CBO有各种毛病,这块在AQE 24讲有介绍。 但是,CBO 也面临三个方面的窘境:“窄、慢、静”。窄指的是适用面太窄,CBO 仅支持注册到 Hive Metastore 的数据表,但在大量的应用场景中,数据源往往是存储在分布式文件系统的各类文件,如 Parquet、ORC、CSV 等等。慢指的是统计信息的搜集效率比较低。对于注册到 Hive Metastore 的数据表,开发者需要调用 ANALYZE TABLE COMPUTE STATISTICS 语句收集统计信息,而各类信息的收集会消耗大量时间。静指的是静态优化,这一点与 RBO 一样。CBO 结合各类统计信息制定执行计划,一旦执行计划交付运行,CBO 的使命就算完成了。换句话说,如果在运行时数据分布发生动态变化,CBO 先前制定的执行计划并不会跟着调整、适配。

    2021-08-23
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部