Spark性能调优

本文讲述了Spark性能调优的第一步——合理配置资源,包括Executor数量、内存和CPU核心。介绍了在Standalone和Yarn模式下的资源分配策略,并强调了增加并行度和内存对性能提升的重要性。还提到了生产环境SparkSubmit脚本的配置示例和如何根据机器性能规划Task数量。

常规性能调优一:最优资源配置

        spark性能调优第一步,就是为任务分配更多的资源,在一定范围内,增加资源的分配与性能的提升是成正比的,实现了最优的资源配置后,在此基础上再考虑进行后面讨论的性能调节策略

        资源的分配在使用脚本提交Spark任务时进行指定,标准的Spark任务提交脚本如一下所示:

/usr/opt/modules/spark/bin/spark-submit \
--class com.atguigu.spark.Analysis \
--num-executors 80 \  240核。16 16台。  480G   64  8台。15*16
--driver-memory 6g \
--executor-memory 6g \
--executor-cores 3 \
/usr/opt/modules/spark/jar/spark.jar 

可以进行分配的资源如表所示

名称

说明

--num-executors

配置Executor的数量

--driver-memory

配置Driver内存(影响不大)

--executor-memory

配置每个Executor的内存大小

--executor-cores

配置每个Executor的CPU core数量

        调节原则: 分配的资源调节到可以使用的资源的最大限度

        对于具体资源的分配,我们分别讨论Spark的两种Cluster运行模式:

        第一种是Spark Standalone模式,你在提交任务前,一定知道或者可以从运维部门获取到你可以使用的资源情况,在编写submit脚本的时候,就根据可用的资源情况进行资源的分配,比如说集群有15台机器,每台机器为8G内存,2个CPU core,那么久指定15个Executor,每个Executor分配8G内存,2个CPU core

        第二种是Spark Yarn模式,由于Yarn使用资源队列进行资源的分配和调度,在表写submit脚本的时候,就根据Spark作业要提交到的资源队列,进行资源的分配,比如资源队列有400G内存,100个CPU core,那么指定50个Executor,每个Executor分配8G内存,2个CPU core

        对上表中的各项资源进行了调节后,得到的性能提高如下表所示:

       

名称解析
增加Executor个数在资源允许的情况下,增加Executor的个数可以执行task的并行度.比如有4个Executor,每个Executor有两个CPU core,那么可以并行执行8个task,如果将Executor的个数增加到8个(资源允许的情况下),那么可以并行执行16个task,此时的并行能力提升了一倍
增加每个Executor的CPU core个数在资源允许的情况下,增加每个Executor的Cpu core个数,可以提高执行task的并行度.比如有4个Executor,每个Executor有两个CPU core,那么可以执行8个task,如果将每个Executor的CPU core个数增加到4个(资源允许的情况下),那么可以并行执行16个task,此时的并行能力提升了一倍

增加每个Executor的内存量

在资源允许的情况下,增加每个Executor的内存量以后,对性能的提升有三点:

1.可以缓存更多的数据(即对RDD进行cache),写入磁盘的数据相应减少甚至可以不写入磁盘,减少了可能的磁盘IO;

2.可以为shuffle操作提供更多内存,即有跟多空间来存放reduce端拉取的数据,写入磁盘的数据相应减少,甚至可以不写入磁盘,减少了可能的磁盘IO;

3.可以为task的执行提供更多内存,在task的执行过程中可能创建很多对象,内存较小时会引发频繁的GC,增加内存后,可以避免频繁的GC,提升整体性能

        补充:生产环境Spark submit脚本配置

        

/usr/local/spark/bin/spark-submit \
--class com.atguigu.spark.WordCount \
--num-executors 80 \
--driver-memory 6g \
--executor-memory 6g \
--executor-cores 3 \
--master yarn-cluster \
--queue root.default \
--conf spark.yarn.executor.memoryOverhead=2048 \
--conf spark.core.connection.ack.wait.timeout=300 \
/usr/local/spark/spark.jar

        基本上根据机器性能进行配置:

        内存量,CPU核

        480G内存.60G,8台服务器.8台--10台服务器

        240核.32核  8台服务器

        第二个问题:如果开始启动脚本:Driver ,怎么规划Task的数量的

        TaskSetScheduler里是Task集合 .10

        按照配置文件:240Task可以并行

        Task要处理Executor中RDD(分区里的数据)

        200个Task并行.3分钟

        250G 250*1024 = 2000分片  30分钟

Spark性能方法主要有以下几种: - **数据倾斜**:例如对数据进行预处理,添加随机前缀。示例代码如下,在化前简单地对单词进行计数,化后通过添加随机前缀并进行两次聚合来缓解数据倾斜问题: ```python # 化前 rdd_data = sc.parallelize(["hello world"]*1000000+["good morning"]*10000+["I love spark"]*10000) rdd_word = rdd_data.flatMap(lambda x:x.split(" ")) rdd_one = rdd_word.map(lambda x:(x,1)) rdd_count = rdd_one.reduceByKey(lambda a,b:a+b+0.0) print(rdd_count.collect()) # 化后 import random rdd_data = sc.parallelize(["hello world"]*1000000+["good morning"]*10000+["I love spark"]*10000) rdd_word = rdd_data.flatMap(lambda x:x.split(" ")) rdd_one = rdd_word.map(lambda x:(x,1)) rdd_mid_key = rdd_one.map(lambda x:(x[0]+"_"+str(random.randint(0,999)),x[1])) rdd_mid_count = rdd_mid_key.reduceByKey(lambda a,b:a+b+0.0) rdd_count = rdd_mid_count.map(lambda x:(x[0].split("_")[0],x[1])).reduceByKey(lambda a,b:a+b+0.0) print(rdd_count.collect()) # 此处仅示范原理,单机上该化方案难以获得性能势 ``` 此方法可缓解数据分布不均匀导致的性能问题[^2]。 - **合理设置分区数量**:分区数量越大,单个分区的数据量越小,任务在不同的core上的数量分配会越均匀,有助于提升任务有效并行度。但partition数量过大,会导致更多的数据加载时间,一般设置分区数是可用core数量的2倍以上20倍以下。可以在spark - submit中用spark.default.parallelism来控制RDD的默认分区数量,可以用spark.sql.shuffle.partitions来控制SparkSQL中给shuffle过程的分区数量[^4]。 - **数据本地化化**:Spark作业运行过程中,Driver会对每一个Stage的task进行分配。Spark希望task能够运行在它要计算的数据所在的节点(数据本地化的思想),这样能够避免数据的网络传输。通常task可能不会被分配到它处理的数据所在的节点,因为这些节点可用的资源可能已经被用完,此时,Spark会等待一段时间,默认3秒,如果等待指定时间后仍然无法在指定节点运行,那么会自动降级,尝试将task分配到比较差的本地化级别所对应的节点上[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值