Spark性能优化指南——初级篇

Spark性能优化指南——初级篇原文来我的公众号:Spark性能优化指南——初级篇 一. Spark作业原理 我们使用spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程。该进程是向集群管理

Spark性能优化指南——初级篇

原文来我的公众号:Spark性能优化指南——初级篇

一. Spark作业原理

我们使用spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程。该进程是向集群管理器(Yarn,K8s)申请运行Spark作业需要使用的资源,这里的资源指的就是Executor进程。
YARN集群管理器会根据我们为Spark作业设置的资源参数,在各个工作节点上,启动一定数量的Executor进程,每个Executor进程都占有一定数量的内存和CPU core。
Spark性能优化指南——初级篇
在申请到了作业执行所需的资源之后,Driver进程就会开始调度和执行我们编写的作业代码了。
Driver进程会将我们编写的Spark作业代码分拆为多个stage,每个stage执行一部分代码片段,并为每个stage创建一批task,然后将这些task分配到各个Executor进程中执行。
task是最小的计算单元,负责执行一模一样的计算逻辑(也就是我们自己编写的某个代码片段),只是每个task处理的数据不同而已。
一个stage的所有task都执行完毕之后,会在各个节点本地的磁盘文件中写入计算中间结果,然后Driver就会调度运行下一个stage。
下一个stage的task的输入数据就是上一个stage输出的中间结果。如此循环往复,直到将我们自己编写的代码逻辑全部执行完,并且计算完所有的数据,得到我们想要的结果为止。
Spark性能优化指南——初级篇
Spark是根据shuffle类算子来进行stage的划分。如果我们的代码中执行了某个shuffle类算子(比如reduceByKey、join等),那么就会在该算子处,划分出一个stage界限来。
可以大致理解为,shuffle算子执行之前的代码会被划分为一个stage,shuffle算子执行以及之后的代码会被划分为下一个stage。
 
因此一个stage刚开始执行的时候,它的每个task可能都会从上一个stage的task所在的节点,去通过网络传输拉取需要自己处理的所有key,然后对拉取到的所有相同的key使用我们自己编写的算子函数执行聚合操作(比如reduceByKey()算子接收的函数)。这个过程就是shuffle。
Spark性能优化指南——初级篇
当我们在代码中执行了cache/persist等持久化操作时,根据我们选择的持久化级别的不同,每个task计算出来的数据也会保存到Executor进程的内存或者所在节点的磁盘文件中。
 
因此Executor的内存主要分为三块:
第一块是让task执行我们自己编写的代码时使用,默认是占Executor总内存的20%;
第二块是让task通过shuffle过程拉取了上一个stage的task的输出后,进行聚合等操作时使用,默认也是占Executor总内存的20%;
第三块是让RDD持久化时使用,默认占Executor总内存的60%。
 
task的执行速度是跟每个Executor进程的CPU core数量有直接关系的。一个CPU core同一时间只能执行一个线程。而每个Executor进程上分配到的多个task,都是以每个task一条线程的方式,多线程并发运行的。
如果CPU core数量比较充足,而且分配到的task数量比较合理,那么通常来说,可以比较快速和高效地执行完这些task线程。
 

二.核心调优参数

num-executors:

该参数用于设置Spark作业总共要用多少个Executor进程来执行。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个工作节点上,启动相应数量的Executor进程。这个参数非常之重要,如果不设置的话,默认只会给你启动少量的Executor进程,此时你的Spark作业的运行速度是非常慢的。(建议50~100个左右的Executor进程)
 

executor-memory:

该参数用于设置每个Executor进程的内存。Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联。(根据作业大小不同,建议设置4G~8G,num-executors乘以executor-memory,是不能超过队列的最大内存量的)
 

executor-cores:

该参数用于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并行执行task线程的能力。因为每个CPU core同一时间只能执行一个task线程,因此每个Executor进程的CPU core数量越多,越能够快速地执行完分配给自己的所有task线程。(建议设置为2~4个,且num-executors * executor-cores不要超过队列总CPU core的1/3~1/2)
 

driver-memory:

该参数用于设置Driver进程的内存(建议设置512M到1G)。
 

spark.default.parallelism:

该参数用于设置每个stage的默认task数量。这个参数极为重要,如果不设置可能会直接影响你的Spark作业性能。(建议为50~500左右,缺省情况下Spark自己根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task。Spark官网建议设置该参数为num-executors * executor-cores的2~3倍较为合适)
 

spark.storage.memoryFraction:

该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6(原则上是尽可能保证数据能够全部在内存中,但如果发现作业发生频繁的GC,就该考虑是否调小)
 

spark.shuffle.memoryFraction:

该参数用于设置shuffle过程中一个task拉取到上个stage的task的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2。也就是说,Executor默认只有20%的内存用来进行该操作。shuffle操作在进行聚合时,如果发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能。(shuffle操作较多时,建议降低持久化操作的内存占比,提高shuffle操作的内存占比比例,避免shuffle过程中数据过多时内存不够用,必须溢写到磁盘上,降低了性能)

 

Randy
微信扫描二维码,关注我的公众号
我的个人网站:
http://www.itrensheng.com/

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/10372.html

(0)
上一篇 2022-12-28
下一篇 2022-12-28

相关推荐

  • oracle 索引失效原因

    oracle 索引失效原因1.查询结果集超过大表的30%会导致索引失效,因为orcale优化器认为既然已经查询了该表的30%以上的数据,那还不如全表扫描。 2.SQL查询条件包含如下条件: not in not exists…

    2023-04-07
    155
  • 以pip为中心的Python软件包管理工具

    以pip为中心的Python软件包管理工具Python作为一门开源语言,其生态系统也非常强大,其中一个重要的组成部分就是其软件包管理工具 – pip。在这篇文章中,我们将会深入了解pip带来的便利以及如何使用它来管理Python的依赖关系。

    2024-09-14
    21
  • 使用Python编程工具Thonny

    使用Python编程工具ThonnyPython是一门易于学习和使用的编程语言,是众多程序员、数据科学家和人工智能从业者所钟爱的语言之一。从Python的运行速度和易用性等方面来说,对新手而言十分友好。然而,学习一门编程语言的过程并不是那么容易,尤其是对于初学者而言。这时候,一个可靠、功能强大且简单易用的集成开发环境(IDE)就非常重要了。Python编程工具Thonny就是这样一款值得推荐的集成开发环境。

    2024-06-09
    46
  • Mysql工作日志「终于解决」

    Mysql工作日志「终于解决」1. DISTINCT效率极差,可以选择替换groupby,最好能在代码内部去重 2. filesort效率也很低 3. 能使用连接查询尽量不要使用子查询 4. in查询包含内容很多的情况下,不要通…

    2023-03-22
    145
  • Python列表序列:简化数据存储和管理

    Python列表序列:简化数据存储和管理Python是一种高级编程语言,它提供了一系列数据结构来处理和管理不同类型的数据。其中,列表序列是处理和存储数据的重要数据结构之一。它提供了一个有序的数据集合,允许您存储和管理多个数据类型,例如数字、字符串、对象等。本文将深入探讨Python列表的使用,帮助您更好地理解和应用这个重要的数据结构。

    2024-04-03
    78
  • OLAP引擎:基于Presto组件进行跨数据源分析

    OLAP引擎:基于Presto组件进行跨数据源分析Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持GB到PB字节,Presto虽然具备解析SQL的能力,但它并不属于标准的数据库范畴。

    2023-04-13
    166
  • c语言重写python代码(python编译成c代码)

    c语言重写python代码(python编译成c代码)由于近几年人工智能的不断发展,Python也跟着火了,因为Python是深度学习技术的主流应用编程语言。同时它的应用场景很多,被称为“胶水语言”。优妹儿就帮小伙伴们科普一下,Python这门神奇编程语言的发展趋势,以及语言特性,帮助想要学习Python的小伙伴们,更清晰的了解它。

    2023-11-26
    137
  • Python函数示例: 将列表元素变成大写字母

    Python函数示例: 将列表元素变成大写字母在Python语言中,有时需要将列表中的元素全部转换为大写或小写字母。此时,可以使用Python内置的upper()和lower()方法。但是,upper()和lower()方法只能针对字符串类型的数据进行操作。因此,当需要将列表中的元素转换为大写或小写字母时,需要用到Python的map()函数。

    2023-12-21
    115

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注