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

09 | 调优一筹莫展,配置项速查手册让你事半功倍!(上)

你好,我是吴磊。
对于 Spark 性能调优来说,应用开发和配置项设置是两个最主要也最常用的入口。但在日常的调优工作中,每当我们需要从配置项入手寻找调优思路的时候,一打开 Spark 官网的 Configuration 页面,映入眼帘的就是上百个配置项。它们有的需要设置 True 或 False,有的需要给定明确的数值才能使用。这难免让我们蒙头转向、无所适从。
所以我经常在想,如果能有一份 Spark 配置项手册,上面分门别类地记录着与性能调优息息相关的配置项就好了,肯定能省去不少麻烦。
那么,接下来的两讲,我们就来一起汇总这份手册。这份手册可以让你在寻找调优思路的时候,迅速地定位可能会用到的配置项,不仅有章可循,还能不丢不漏,真正做到事半功倍!

配置项的分类

事实上,能够显著影响执行性能的配置项屈指可数,更何况在 Spark 分布式计算环境中,计算负载主要由 Executors 承担,Driver 主要负责分布式调度,调优空间有限,因此对 Driver 端的配置项我们不作考虑,我们要汇总的配置项都围绕 Executors 展开那么,结合过往的实践经验,以及对官网全量配置项的梳理,我把它们划分为 3 类,分别是硬件资源类、Shuffle 类和 Spark SQL 大类。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文是一篇关于Spark性能调优配置项的速查手册。作者通过对Spark配置项的分类,分别介绍了与硬件资源、Shuffle操作和Spark SQL相关的配置项。在硬件资源类中,作者详细介绍了与CPU和内存设置相关的配置项,包括spark.cores.max、spark.executor.cores、spark.task.cpus、spark.default.parallelism、spark.sql.shuffle.partitions等参数。对于CPU设置,作者强调了并行度和并行计算任务的关系,以及它们对数据粒度和内存消耗的影响。在内存设置方面,作者介绍了堆内内存和堆外内存的管理模式,以及相应的配置项含义和设置方法。文章还讨论了User Memory的分配和作用,以及如何根据应用中的自定义数据结构来调整内存区域的相对占比。总的来说,本文通过对Spark配置项的分类和详细介绍,为读者提供了快速了解和使用Spark性能调优配置项的指南。文章内容涵盖了硬件资源、内存管理和数据结构存储等方面,对于需要进行Spark性能调优的读者来说,是一份非常有价值的参考资料。文章还提到了与磁盘设置有关的配置项spark.local.dir,以及如何平衡Execution Memory与Storage Memory。同时,作者还提出了每日一练的问题,引导读者深入思考和学习。整体而言,本文内容丰富,涵盖了多个方面的Spark性能调优配置,对读者进行快速了解和深入学习都具有很高的参考价值。

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

全部留言(30)

  • 最新
  • 精选
  • Joe
    老师,针对spark.sql.shuffle.partitions的使用有一些疑问? 1. 如果df1.join(df2),df1用的是hash partitioner并且分区数是3,这种情况在reduce端参数spark.sql.shuffle.partitions会生效吗?还是以df1的分区为准? 2. 这个参数是针对所有的Dataframe,DataSet和SQL,还是只有SQL生效?

    作者回复: 先来回答第二个问题,这个参数对所有的DF、DS、SQL都生效。 再来说第一个问题,例子蛮好的。先说答案,然后咱们再去分析:对于你这种情况,两张表都会Shuffle。当然,假设你的表都很大,超过广播阈值,能转换成Broadcast join那就另当别论了。 为什么呢?spark.sql.shuffle.partitions默认是200。 这部分其实需要一些“前置引用”的知识,这些知识其实是在22讲Physical Planning才会涉及,所以在这一讲这里会比较难理解。 是这样的,Spark SQL执行计划中的每一个节点,都有4个重要的属性,分别是: 节点要求的输入: 1)requiredChildDistribution 2)requiredChildOrdering 节点的输出: 3)outputPartitioning 4)outputOrdering 每个节点都有输出的分区情况、排序情况,也就是3)、4);同时,每个节点对于自己的子节点,都有关于 分区和排序的要求,也就是1)、2)。 当子节点的分区与排序情况,不满足当前节点的输入要求时,Spark SQL就会在Physical planning阶段,强行插入一些中间节点,比如Exchange(Shuffle)。 回到你的问题,join要求子节点(df1、df2)的outputPartitioning是以joinKey为分区键,分成200个分区(因为spark.sql.shuffle.partitions默认值是200)。但是,你的df1,有3个分区;df2未知,因此,Spark SQL会在物理计划阶段给两个子节点,也就是df1、df2强行插入Exchange、也就是Shuffle。这两个Shuffle,会分别把df1、df2变成是有200个分区的分布式数据集。两个Shuffle做完之后,才会计算后面的Join。 所以,最终的分区,不是df1的3、也不是df2原来的分区,而是spark.sql.shuffle.partitions参数设定的值。

    2021-04-29
    39
  • 斯盖丸
    关于spark.sql.shuffle.partitions 老师实际工作中我发现这个参数不管用。比如我把它设成2000,并去读parquet文件,大约几百个文件吧,但我看task数量只有80个,而且还一直在变,有时会更少。网上说spark-sql的并行度不管用,要自己手动repartition,是这样吗?task数量一直在变是因为不断地在做groupBy和join吗?那为什么task数量始终达不到我设的spark.sql.shuffle.partitions = 2000呢?

    作者回复: 这块确实有点坑,只有你的计算中涉及Joins或是聚合,spark.sql.shuffle.partitions,这个参数的设置,才会影响Shuffle Reduce阶段的并行度。如果你的作业没有Joins或是聚合计算,那确实,这个参数设了也是摆设。 比如你仅仅是读Parquet,然后想通过这个参数调整并行度,确实是徒劳,这个时候,你确实只能自己用repartition或是Coalesce去做重分区。

    2021-04-16
    5
    18
  • 断笔画墨
    spark读取oracle表,oracle表结构没有数值类型,大部分都是varchar,数据量上亿,怎么在源端做高并发读取啊

    作者回复: 我理解数据读取效率和字段类型没什么关系,要提高并行计算效率,可以考虑使用API: spark.read.jdbc(url, table, predicates, props) 其中url就是你的Oracle DB table是表名 props是各种属性,比如权限信息,如user,password predicates比较关键,是划分数据分区的谓词数组,比如["id between 1 and 100", "id between 101 and 200", ... "id between 901 and 1000"],本质上就是用这些过滤条件把查询分成多个,每个查询的结果都是一个数据分片。这么做的好处,是可以提高Spark的并行度,但是要注意,同时发这么多查询请求给Oracle,要注意Oracle数据库本身的并发处理能力。

    2021-04-24
    3
    14
  • Geek_d794f8
    Spark.task.cpus这个参数的设置,我之前理解就是一个cpu核运行一个task。难道还可以0.5个cpu或者多个cpu运行一个task吗?

    作者回复: 好问题,通常来说,这个参数都不需要动,默认就是1。回答你的问题,这个值,不能小于1。那么大于1是什么情况呢?就是你的task本身,是需要多线程操作的,比如一个线程把数据写到HDFS,另外一个线程,通过JDBC同时把数据塞进DBMS,诸如此类。 Spark.task.cpus这个参数的意思,在于Spark为这种特殊的多线程task提供了一种开放的可能,允许你去设置大于1的cpu core。但允许不代表你一定要这么做哈 特别注意的是,如果你的task没什么特别,但你还是设置的大于1的数值,那cpu就是白白浪费。spark只会去同时launch (spark.executor.cores / spark.task.cpus)这么多的tasks。

    2021-04-15
    12
  • 快跑
    Class Student是存在User Memory? new Student("小明")是存在Executor Memory?

    作者回复: 这个其实取决于你把对象放在哪里。 分两种情况来看哈~ 1. 如果你用RDD封装这些自定义类型,比如RDD[Student],那么,数据集消耗的是Execution memory。 2. 相反,如果你是在处理分布式数据集的函数中,new Student来辅助计算过程,那么这个对象,是放在User memory里面的。

    2021-04-13
    3
    11
  • Geek_d794f8
    老师是不是可以这样理解,spark-submit提交任务的时候申请的总cores数为10,yarn调度系统会分配10个v-core,如果集群资源充足,实际上一个v-core就是对应一个cpu核,如果资源不够,相当于就不是一对一,此时集群最大的task并行度并不是10,而是并发度为10。 以上理解对吗?

    作者回复: 并行度和并发度是两个完全不同的概念,一个数据视角——并行度;一个是计算视角——并发度,这个我们本讲应该有过介绍哈~ 另外你说的spark.executor.cores与v-core的对应关系是没问题的。但是cores也好,v-core也罢,物理上不见得对应的是一个物理CPU core,这个要看CPU的硬件配置,有些CPU只能起一个线程,不过大部分现代CPU都能起两个线程。所以spark.executor.cores与v-core,更准确的对应,是线程,而不是物理上的CPU core。这个地方其实有点绕,需要注意。

    2021-04-15
    7
  • 快跑
    一个任务报错Container Killed by Yarn For Exceeding Memory Limits Consider boosting spark.yarn.executor.memoryOverhead 我按照提示增加spark.yarn.executor.memoryOverhead,任务的确执行通过。 请教老师spark.yarn.executor.memoryOverhead参数控制哪部分内存,主要负责什么?什么情况下会用到这部分内存。文章中关于内存的好像没有提到这部分。

    作者回复: spark.executor.memoryOverhead ,在yarn、k8s部署模式下,container会预留一部分内存,形式是堆外,用来保证稳定性,主要存储nio buffer,函数栈等一些开销,所以你看名字:over head。这部分内存,他的目的是保持Spark作业运行时的稳定性。 这个failure,报这个错,说明overhead空间不足,系统必须的开销没有足够的空间~ 调大就行了~ 这部分内存和执行性能关系不大,所以咱们课程里没有提。

    2021-04-19
    3
    6
  • 老师,这个自定义结构不是很懂,什么样的数据格式是自定义数据格式,我现在经常接触到的是spark-submit 提交sparksql这一块,用的是hive表,这个涉及自定义数据结构吗

    作者回复: 好问题,你可以这么来理解,凡是数据源,不管是Hive来的,还是HDFS来的,还是S3来的,不管是什么格式,比如Parquet、ORC,这些数据源,consume的都是执行内存,当然,如果他们被cache了,那就消耗Storage memory。 那些开发者自己自定义的类、类型、数据结构、Struct,等等,这些东西往往用来辅助完成对于刚刚说的那些数据源的处理,这些辅助性的类、类型、数据结构、Struct,才是自定义数据结构。他们消耗的,就是user memory。

    2021-04-12
    5
  • Sean
    根据老师的回回复,个人总结如下,不知是否正确:在不使用yarn,k8s模式下,完全没有必要启用off heap,而且在钨丝计划的加持下,可以理解为使用堆内内存,不会对任务有任何影响,但在使用yarn或k8s模式下,必须要开启off heap,否则会出现t Container Killed by Yarn For Exceeding Memory Limits Consider boosting spark.yarn.executor.memoryOverhead报错,需要调大spark.yarn.executor.memoryOverhead

    作者回复: 对的,总结的很到位~

    2021-08-22
    3
    4
  • 西南偏北
    并行度太高可能会造成任务调度耗时超过任务处理耗时,如果不进行后续分区合并,还有会造成小文件问题(比如写入Hive)

    作者回复: 满分💯

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