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

20 | RDD和DataFrame:既生瑜,何生亮?

你好,我是吴磊。
从今天开始,我们进入 Spark SQL 性能调优篇的学习。在这一篇中,我会先带你学习 Spark SQL 已有的优化机制,如 Catalyst、Tungsten 这些核心组件,以及 AQE、DPP 等新特性。深入理解这些内置的优化机制,会让你在开发应用之初就有一个比较高的起点。然后,针对数据分析中的典型场景,如数据关联,我们再去深入探讨性能调优的方法和技巧。
今天这一讲,我们先来说说 RDD 和 DataFrame 的渊源。这也是面试的时候,面试官经常会问的。比如说:“Spark 3.0 大版本发布,Spark SQL 的优化占比将近 50%;而像 PySpark、Mllib 和 Streaming 的优化占比都不超过 10%,Graph 的占比几乎可以忽略不计。这是否意味着 Spark 社区逐渐放弃了其他计算领域,只专注于数据分析?”
这个问题的标准答案是:“Spark SQL 取代 Spark Core,成为新一代的引擎内核,所有其他子框架如 Mllib、Streaming 和 Graph,都可以共享 Spark SQL 的性能优化,都能从 Spark 社区对于 Spark SQL 的投入中受益。”不过,面试官可没有那么好对付,一旦你这么说,他 / 她可能会追问:“为什么需要 Spark SQL 这个新一代引擎内核?Spark Core 有什么问题吗?Spark SQL 解决了 Spark Core 的哪些问题?怎么解决的?”
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Spark SQL中的RDD和DataFrame是两种不同的数据抽象,本文从它们的渊源出发,探讨了它们的必然性和区别。首先,文章指出RDD在开发模式下存在优化空间受限的问题,特别是在PySpark中性能表现不佳。为解决这一问题,DataFrame应运而生,携带数据模式的结构化分布式数据集,为Spark引擎的内核优化打开了全新的空间。DataFrame的出现不仅仅是API上的改动,更为Spark引擎的内核优化提供了新的可能性。文章还介绍了Spark SQL的核心组件Catalyst和Tungsten,以及Catalyst的优化过程,阐述了DataFrame开发模式对Catalyst优化过程的影响。整体而言,文章通过对RDD和DataFrame的对比,以及DataFrame对Spark引擎优化的意义,深入浅出地阐述了DataFrame的必然性和技术特点。 文章还指出,基于DataFrame简单的标量算子和明确的Schema定义,借助Catalyst优化器和Tungsten,Spark SQL有能力在运行时构建起一套端到端的优化机制。这套机制运用启发式的规则与策略,以及运行时的执行信息,将原本次优、甚至是低效的查询计划转换为高效的执行计划,从而提升端到端的执行性能。在DataFrame的开发框架下,所有子框架、以及PySpark,都运行在Spark SQL之上,都可以共享Spark SQL提供的种种优化机制,这也是为什么Spark历次发布新版本、Spark SQL占比最大的根本原因。文章深入浅出地阐述了DataFrame的必然性和技术特点,为读者提供了对Spark SQL中RDD和DataFrame的深入理解。

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

全部留言(14)

  • 最新
  • 精选
  • Fendora范东_
    对RDD和DataFrame的理解 1.首先区分这两个东西,RDD分布式数据集;DF是带数据模式的结构化分布式数据集。核心区别在于DF带数据模式(感觉像传统分布式数据库中的一张表),RDD不带数据模式或者说是泛型的。 2.其次是这两者分别提供的API,RDD API优化引擎是Spark Core(没理解这句话,我理解Spark Core负责task调度计算存储,和优化的联系在哪呢?);DF API优化引擎是SparkSQL,包括Catalyst执行过程优化和Tungsten数据结构优化。两者API的区别在于一个提供标量算子一个高阶算子和两者底层优化引擎不一致。 3.上面两组概念应该区分开。之前子框架如Streaming,mlib,graph都是采用RDD API来编写,现在都是采用DF API来重新编写。 4.调用DF API生成DF,但DF 的action算子触发执行后最终还是生成RDD,通过Spark Core框架来进行调度计算。所以可不可以认为DF API+SparkSQL就是代替了之前的RDD API?目的就是为了提供更简单的API,让Spark做统一优化,在rdd计算时更高效?

    作者回复: Perfect x 4 ! 理解得非常到位了~ 老弟的概括能力很强,确实,把握这4点,关于RDD和DataFrame的区别与联系,其实就算是吃透了。 关于你说的第二点,确实,Spark Core实际就是分布式运行时,负责分布式任务调度、执行,严格来说,并不存在什么优化机制,仅仅是分发分布式代码、运行、状态交互,等等。 第四点说得尤其到位,大赞👍

    2021-04-30
    2
    14
  • sky_sql
    老师好,DataFrame和RDD这两套独立的API,最终还是会转化为RDD之上的计算吧?

    作者回复: 对,没错,DataFrame的code,经过Spark SQL优化之后,最终交由Tungsten生成代码和RDD[InternalRow],代码交由DAGScheduler进行分发、运行在RDD[InternalRow]之上。 后面的21、22、23会详细展开从DataFrame到Catalyst、再到Tungsten,最终生成代码和RDD的过程,可以重点关注下哈~

    2021-04-29
    10
  • CycleGAN
    老师好,我们的业务有很复杂的计算udf,用dsl或者sql无法描述,PySpark嵌入udf,使得优化无能为力,性能也一直很低,我们对于反复使用的数学操作会编译成so执行,也在提升udf本身的执行效率,请问将python的udf改写成scala提升会大吗?老师对于我们写复杂udf有什么建议吗?

    作者回复: 好问题,UDF本身的开销其实大家有目共睹。不过对于你的cases来说,其实没办法武断地说用Scala重写效果如何。因为就像咱们最开始讲调优方法论的时候一样,其实这取决于UDF本身是不是整体作业的瓶颈。 对于UDF的优化,我觉得不妨这样,就是从你众多的UDF中,选中一个开销最大的,或者至少是“看上去”开销最大的,然后用Scala优化,对比前后作业端到端的执行效果,然后再去决定,要不要对其他UDF做同样的优化。 另外,对于复杂的业务逻辑,如果DSL和SQL都无法实现,除了UDF,其实还可以考虑用Script Transformation,这块Facebook有个最佳实践,可以参考下,看看对你们是否有帮助:https://databricks.com/session_eu19/powering-custom-apps-at-facebook-using-spark-script-transformation

    2021-05-16
    5
    6
  • Geek_d794f8
    磊哥,Tungsten 使用定制化的数据结构 Unsafe Row 来存储数据,是不是指的cache缓存的时候使用Unsafe Row存储的数据,或是shuffle溢写到磁盘的时候存储的结构,还是说从数据源读进来的时候会转化成Unsafe Row的结构?

    作者回复: 都对,或者换句话说,只要是走Spark SQL的流程(DataFrame、Dataset、SQL三种API),就都能利用到Tungsten的这种二进制Unsafe Row。比如,就像你说的: 1)缓存的时候,可以利用得到,Tungsten用Unsafe Row来封装每条数据记录; 2)数据源读进来的时候(当然这么说不太严谨,严格来说,应该是Tungsten生成的“手写代码”交付执行的时候,在运行时执行读取数据源的时候,会把它convert成Tungsten的二进制Unsafe Row); 3)Shuffle的时候也是一样,不仅如此,Shuffle还能利用文中介绍的Memory Page(一个JVM对象),来进一步提升内存的利用效率。

    2021-04-29
    6
  • 西南偏北
    PySpark应用中如果用到了Python里面的数据结构都会导致在JVM进程和Python进程间进行交互的吧

    作者回复: 对没错,除此之外,还有万恶的UDF。

    2021-05-05
    5
  • Z宇锤锤
    Java Object 在对象存储上为什么会有比较大的开销? 我查阅了了一些资料,Java对象的存储在JVM上至少需要32或64Bit的字节存储对象自身信息,哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳。 "ABCD"的存储至少需要8个字节。

    作者回复: 是的,你说的这些开销都对,不过“ABCD”在JVM中实际需要48个字节才能存下哈~ 我怀疑你是不是漏打了个4,哈哈~ 具体计算细节可以参考这里:https://databricks.com/blog/2015/04/28/project-tungsten-bringing-spark-closer-to-bare-metal.html

    2021-05-02
    4
    4
  • 曾经看到一个视频,说是Dataset后续要取代DataFrame。Dataset和DataFrame这两者之间有什么关系?实际项目中用的哪个偏多些?

    作者回复: 好问题~ DataFrame和Dataset的关系,非常紧密。 首先,DataFrame实际上是Dataset[Row],不论是DataFrame、还是Dataset,他们都能享受到Spark SQL带来的性能红利,因此在执行效率上,二者没有区别。 因此,两者的区别,最主要的,还是在开发效率。DataFrame其实就是二维表,承载结构化数据。Dataset可以用来处理非结构化数据,但是Dataset需要用户明确定义数据类型,比如自定义的Person、School之类的。 所以总结下来,如果需要处理结构化数据,一般大家都会用DataFrame,因为简单直接,不需要自定义User Class,省去这一步的麻烦。但如果需要从(非结构化)日志解析一些内容,往往会用Dataset先把数据抽出来,得到结构化数据之后,再考虑转成DataFrame,方便后续处理。 一言以蔽之,没有优劣之分,只有不同的适应场景。一般来说,DataFrame用的偏多,因为大部分情况,我们处理的都是结构化数据。相应地,Dataset用的就会少一些。另外,Dataset取代DataFrame这种说法,听听就好了,不用特别当真~

    2021-11-01
    3
  • Z宇锤锤
    RDD和DataFrame的最大区别,DF像是一张二维表,可以用来写SQL。RDD只能使用算子。

    作者回复: DF确实就是二维表,和RDD相比,除了API的区别之外,最大的区别,还是DF可以走Spark SQL做优化~

    2021-05-02
    2
    1
  • Geek_d794f8
    Tungsten的这种存储数据结构,感觉和parquet类似,他们之间有什么关联吗

    作者回复: 确实有相似之处,毕竟都是用二进制的形式来存储数据,所以会有相通的地方。 不过,两者没啥联系哈,实际上,我倒是觉得,Parquet的数据结构,要比Tungsten的复杂得多。

    2021-04-29
    3
    1
  • sky_sql
    RDD是Spark对于分布式数据模型的抽象,调度、存储都是RDD维度的,DataFrame底层是使用RDD的算子实现的吧? 对于普通开发者后面使用DataFrame实现业务逻辑,尽量不使用RDD?

    作者回复: DataFrame底层不是RDD实现的,DataFrame和RDD是两套独立的API。区别在于,RDD的优化引擎是Spark Core;而DataFrame的优化引擎是Spark SQL,这个我们后面3讲:21、22、23会详细的介绍哈~ 对于开发者来说,强烈推荐DataFrame开发API,放弃RDD开发API。Spark SQL的优化机制远胜于Spark Core,换句话说,同样的业务应用,仅仅是API不同,你用DataFrame开发的code,天然地就比你用RDD开发的code,在执行效率上面更高,啥都不用调优,天然就更快。

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