49.性能调优之调节并行度

来源:互联网 发布:iphone美图软件 编辑:程序博客网 时间:2024/05/16 03:16

本文为《Spark大型电商项目实战》 系列文章之一,主要介绍使用调节并行度的方式进行性能调优,重点讲解 Spark并行度原理以及如何调节并行度。

Spark并行度原理

这里写图片描述

以 Spark 中的 WordCount 作业为例,每个Spark作业其实都是一个 Application,每个 Application 对应多个 Jobs,一个 action 操作(比如 collect)触发一个 job,在WordCount程序中有一个 job,每个 job 拆成多个 stage(发生 shuffle 的时候回拆分出一个 stage),reduceByKey 处会发生 shuffle。reduceByKey 这里,相当于 stage0 的task在最后执行到 reduceByKey 的时候会为每个 stage1 的task都创建一份文件(也可能是合并在少量的文件里面),每个 stage1 的 task会去各个节点上的各个 task 创建的属于自己的那一份文件里面拉取数据,每个 stage1 的 task 拉取到的数据一定是相同 key 对应的数据。对相同的key,对应的values,才能去执行我们自定义的function操作(_ + _)。

task会找到 HDFS 上属于自己的对应数据,每个 task 处理一小块数据 HDFS block,然后依次去执行算子操作。task 默认会创建三份文件,每一个文件里面,一定是存放相同的key对应的values;但是一个文件里面可能有多个key,以及其对应的values;相同key的values一定是进入同一个文件。

下一个 stage 的每个 task 都会去上一个 stage 的 task 里拉去属于自己的那份文件。

并行度设置

并行度其实就是指的是Spark作业中各个stage的task数量,也就代表了Spark作业的在各个阶段(stage)的并行度。

如果不调节并行度,导致并行度过低会怎么样?
假设现在已经在spark-submit脚本里面,给我们的spark作业分配了足够多的资源,比如有50个 executor,每个executor 有10G内存,每个 executor 有3个cpu core,基本已经达到了集群或者yarn队列的资源上限。

如果 task 没有设置,或者设置的很少,比如就设置了100个 task。现在50个 executor,每个executor 有3个cpu core,也就是说,你的Application任何一个 stage 运行的时候都有总数在150个 cpu core,可以并行运行。但是你现在只有100个task,平均分配一下,每个executor 分配到2个task,那么同时在运行的task只有100个,每个executor只会并行运行2个task,每个executor剩下的一个 cpu core 就浪费掉了。

你的资源虽然分配足够了,但是问题是,并行度没有与资源相匹配,导致你分配下去的资源都浪费掉了。

合理的并行度的设置,应该是要设置的足够大,大到可以完全合理的利用你的集群资源。比如上面的例子,总共集群有150个cpu core,可以并行运行150个task。那么就应该将你的Application 的并行度至少设置成150才能完全有效的利用你的集群资源,让150个task并行执行,而且task增加到150个以后,既可以同时并行运行,还可以让每个task要处理的数据量变少。比如总共150G的数据要处理,如果是100个task,每个task计算1.5G的数据,现在增加到150个task可以并行运行,而且每个task主要处理1G的数据就可以。

很简单的道理,只要合理设置并行度,就可以完全充分利用你的集群计算资源,并且减少每个task要处理的数据量,最终,就是提升你的整个Spark作业的性能和运行速度。

  1. task数量,至少设置成与Spark application的总cpu core数量相同(最理想情况是:比如总共150个cpu core,分配了150个task,一起运行,差不多同一时间运行完毕)。

  2. 官方推荐task数量设置成spark application总cpu core数量的2~3倍,比如150个cpu core基本要设置task数量为300~500。实际情况与理想情况不同的,有些task会运行的快一点,比如50s就完了,有些task可能会慢一点,比如要1分半才运行完,所以如果你的task数量,刚好设置的跟cpu core数量相同,可能还是会导致资源的浪费,因为,比如150个task,10个先运行完了,剩余140个还在运行,但是这个时候,有10个cpu core就空闲出来了,就导致了浪费。那如果task数量设置成cpu core总数的2~3倍,那么一个task运行完了以后,另一个task马上可以补上来,就尽量让cpu core不要空闲,同时也是尽量提升spark作业运行的效率和速度,提升性能。

  3. 如何设置一个Spark Application的并行度?
    可以使用参数spark.default.parallelism设置,比如

    SparkConf conf = new SparkConf().set("spark.default.parallelism", "500")

总结

分配更多资源属于“重剑无锋”类型:真正有分量的一些技术和点,其实都是看起来比较平凡,看起来没有那么“炫酷”,但是其实是你每次写完一个spark作业,进入性能调优阶段的时候,应该优先调节的事情,就是这些(大部分时候,可能资源和并行度到位了,spark作业就很快了,几分钟就跑完了)
后续会进行一些“炫酷”的调优方式,比如数据倾斜(100个spark作业,最多10个会出现真正严重的数据倾斜问题)JVM调优等等。

《Spark 大型电商项目实战》源码:https://github.com/Erik-ly/SprakProject

本文为《Spark大型电商项目实战》系列文章之一,
更多文章:Spark大型电商项目实战:http://blog.csdn.net/u012318074/article/category/6744423

0 0