spark task与stage数量过多调优

图片发自简书App

昨天群里的一个朋友出现了任务执行过慢。

通过运行过程来看,我们发现task比较多,更值得注意的是这些task都在一个stage之中。

首先要分析这个问题我们应该要清楚task和stage的关系。

 

图片发自简书App

通过这个图我们可以看出job-stage-task的对应关系。首先job的划分是遇到action操作时,被发现后经过sparkcontext的runjob方法来到DAGscheduler,这个类中它会通过依赖关系划分出stage,一个stage是一个taskset,里面的每个task对应着rdd的一个分区。task可以理解为并行的分片。

 

理解了一个分区对应一个task后,可以分析得出这个问题是分区过多造成的问题。

那么我们再来看看分区数是怎么设定的。

如果在spark-default.conf中没有显示设置的话。会按照不同模式给不同的默认分区数。(spark.default.parallelism)

对于local[N]模式,因为开辟了N个线程,所以有N个core,也就默认分区为N。如果单用local那么只会开起一个分区。

如果是伪分布模式,local-cluster[x,y,z] 那么默认分区是x*y,x代表的是运行的executor数量,y是每个executor有多少个core。

如果是yarn或者是standalone模式。是用的函数max(x*y,2)前者的含义和伪分布一样,后者表示如果x*y<2,分区就取2。

在程序读取创建RDD的时候,一般会用textFile,这个函数可以读取本地或者是hdfs的文件。分区数为

rdd的分区数 = max(本地file的分片数, sc.defaultMinPartitions)
rdd的分区数 = max(hdfs文件的block数目, sc.defaultMinPartitions)

 

但是对于用 sc.parallelize创建的数据,是用的默认分区,也可以在第二个参数中进行显示的设置。

 

对于问题本身:task过多,原因是分区的问题。我们应该从分区入手,是输入的小文件太多,还是本来就会有大数据量。在分区过多时,限定分区个数看看性能是否提高,也可以在filter等操作后对分区进行一定缩减。大量使用shuffle操作使task增加(这个应该不是本问题原因,但是我们应该考虑这也是让task增加的原因),这样会完成多个stage串行会降低效率。

 

当我们真的无法避免这么多task时候,我们应该用最佳的参数进行调优。下面参数是来自浪尖的建议

1) executor_cores*num_executors 不宜太小或太大!一般不超过总队列 cores 的 25%,比如队列总 cores 400,最大不要超过100,最小不建议低于 40,除非日志量很小。

 

2) executor_cores 不宜为1!否则 work 进程中线程数过少,一般 2~4 为宜。

3) executor_memory 一般 6~10g 为宜,最大不超过 20G,否则会导致 GC 代价过高,或资源浪费严重。

4) spark_parallelism 一般为 executor_cores*num_executors 的 1~4 倍,系统默认值 64,不设置的话会导致 task 很多的时候被分批串行执行,或大量 cores 空闲,资源浪费严重。

5) driver-memory 早前有同学设置 20G,其实 driver 不做任何计算和存储,只是下发任务与yarn资源管理器和task交互,除非你是 spark-shell,否则一般 1-2g 就够了。

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Spark中每个stagetask数量取决于输入数据的分区数和集群中可用的计算资源。一般来说,每个分区都会被分配一个task来处理,因此,如果输入数据有100个分区,那么一个stage就会有100个task。但是,如果集群中只有50个可用的计算资源,那么这个stage就会被分成两个子stage,每个子stage有50个task。因此,Sparkstagetask数量是动态变化的,取决于输入数据和集群资源的情况。 ### 回答2: 在Spark中,任务(Task)是指在一个分布式环境中由executor执行的计算任务。而Stage则是指一个有相同Shuffle操作的task集合。 Spark中的任务数量是指每个Stage中的任务数。根据Spark的流程,每个Stage会被划分为不同的Task。这些Task是由executor执行的,并且通过RDD的partition进行区分。因此,每个Stage中的任务数取决于RDD的partition数量,也就是数据块的数量。 在Spark中,一个RDD的partition数量通常是用户通过`repartition()`和`coalesce()`函数手动设置的。如果未手动设置,则默认使用Spark的自动分区算法。这个自动分区算法会将数据均匀的分散到集群的每个节点上,尽可能的保证每个partition的大小相同。 一般来说,Spark中每个Task会处理一个partition的数据块。因此,Task数量直接取决于partition的数量。如果一个Stage中有一个RDD,而这个RDD有100个partition,那么这个Stage就会有100个Task。如果一个Stage中有两个RDD(RDD1有50个partition,RDD2有20个partition),那么这个Stage就会有70个Task,因为不同的RDD之间需要进行Shuffle,即数据的重分配和排序。 需要注意的是,任务数量是一个较为理论的概念,实际中并不一定完全按照这个数量进行划分。例如,资源限制和任务之间的依赖关系等因素都可能影响任务数量Spark中也提供了一些参数来限制Task数量,例如`spark.default.parallelism`参数可以设置默认的并行度。 综上所述,SparkStage的任务数量取决于RDD的partition数量和每个Stage中有多少个RDD。在实际使用中,可以通过整RDD的partition数量Spark的默认并行度等参数来化任务数量和性能。 ### 回答3: Spark中的Stage是指一组可以并行执行的任务,通常是用户在代码中定义的一系列数据转换操作。在Spark应用程序中,可以通过Spark UI或者Spark日志来查看每个Stage的任务数量。 每个Stage中的任务数量取决于输入数据量以及执行过程中分区数的数量Spark会把输入数据划分为不同的分区,每个分区都是一个独立的任务,Spark会把这些分区分配给不同的Executor并发执行。因此,输入数据量越大,任务数量就越多。 同时,每个Stage执行的数据转换操作也会影响任务数量。例如,如果用户在代码中使用了groupByKey或者reduceByKey等聚合操作,Spark会根据key的值对数据进行分组或聚合,并生成多组数据,每组数据都需要独立处理。这样就会导致任务数量增多,同时也会影响Spark的性能。 总之,每个Stage中的任务数量是由输入数据量、执行过程中的分区数以及数据转换操作的类型等多个因素决定的。为了保证Spark应用程序的性能和效率,需要根据实际情况合理设置输入数据和分区数,尽量避免不必要的数据转换操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值