大数据开发-Spark调优常用手段

Spark调优

spark调优常见手段,在生产中常常会遇到各种各样的问题,有事前原因,有事中原因,也有不规范原因,spark调优总结下来可以从下面几个点来调优。

1. 分配更多的资源

分配更多的资源:
  它是性能优化调优的王道,就是增加和分配更多的资源,这对于性能和速度上的提升是显而易见的,
  基本上,在一定范围之内,增加资源与性能的提升,是成正比的;写完了一个复杂的spark作业之后,进行性能调优的时候,首先第一步,就是要来调节最优的资源配置;
  在这个基础之上,如果说你的spark作业,能够分配的资源达到了你的能力范围的顶端之后,无法再分配更多的资源了,公司资源有限;那么才是考虑去做后面的这些性能调优的点。

相关问题:
(1)分配哪些资源?
(2)在哪里可以设置这些资源?
(3)剖析为什么分配这些资源之后,性能可以得到提升?

1.1 分配哪些资源

executor-memory、executor-cores、driver-memory

1.2 在哪里可以设置这些资源

在实际的生产环境中,提交spark任务时,使用spark-submit shell脚本,在里面调整对应的参数。

 提交任务的脚本:
 spark-submit \
 --master spark://node1:7077 \
 --class com.hoult.WordCount \
 --num-executors 3 \    配置executor的数量
 --driver-memory 1g \   配置driver的内存(影响不大)
 --executor-memory 1g \ 配置每一个executor的内存大小
 --executor-cores 3 \   配置每一个executor的cpu个数
 /export/servers/wordcount.jar

1.2 参数调节到多大,算是最大

  • ==Standalone模式==
先计算出公司spark集群上的所有资源 每台节点的内存大小和cpu核数,
   比如:一共有20台worker节点,每台节点8g内存,10个cpu。
   实际任务在给定资源的时候,可以给20个executor、每个executor的内存8g、每个executor的使用的cpu个数10。
  • ==Yarn模式==
先计算出yarn集群的所有大小,比如一共500g内存,100个cpu;
   这个时候可以分配的最大资源,比如给定50个executor、每个executor的内存大小10g,每个executor使用的cpu个数为2。
  • 使用原则
在资源比较充足的情况下,尽可能的使用更多的计算资源,尽量去调节到最大的大小

1.3 为什么调大资源以后性能可以提升

--executor-memory

--total-executor-cores 

2. 提高并行度

2.1 Spark的并行度指的是什么

spark作业中,各个stage的task的数量,也就代表了spark作业在各个阶段stage的并行度!
    当分配完所能分配的最大资源了,然后对应资源去调节程序的并行度,如果并行度没有与资源相匹配,那么导致你分配下去的资源都浪费掉了。同时并行运行,还可以让每个task要处理的数量变少(很简单的原理。合理设置并行度,可以充分利用集群资源,减少每个task处理数据量,而增加性能加快运行速度。)

2.2 如何提高并行度

2.2.1 可以设置task的数量

至少设置成与spark Application 的总cpu core 数量相同。
最理想情况,150个core,分配150task,一起运行,差不多同一时间运行完毕
官方推荐,task数量,设置成spark Application 总cpu core数量的2~3倍 。

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

2.2.2 如何设置task数量来提高并行度

设置参数spark.default.parallelism
   默认是没有值的,如果设置了值为10,它会在shuffle的过程才会起作用。
   比如 val rdd2 = rdd1.reduceByKey(_+_) 
   此时rdd2的分区数就是10

可以通过在构建SparkConf对象的时候设置,例如:
   new SparkConf().set("spark.defalut.parallelism","500")

2.2.3 给RDD重新设置partition的数量

使用rdd.repartition 来重新分区,该方法会生成一个新的rdd,使其分区数变大。
此时由于一个partition对应一个task,那么对应的task个数越多,通过这种方式也可以提高并行度。

2.2.4 提高sparksql运行的task数量

http://spark.apache.org/docs/2.3.3/sql-programming-guide.html

通过设置参数 spark.sql.shuffle.partitions=500  默认为200;
可以适当增大,来提高并行度。 比如设置为 spark.sql.shuffle.partitions=500

专门针对sparkSQL来设置的

3. RDD的重用和持久化

3.1 实际开发遇到的情况说明

如上图所示的计算逻辑:
(1)当第一次使用rdd2做相应的算子操作得到rdd3的时候,就会从rdd1开始计算,先读取HDFS上的文件,然后对rdd1做对应的算子操作得到rdd2,再由rdd2计算之后得到rdd3。同样为了计算得到rdd4,前面的逻辑会被重新计算。

(3)默认情况下多次对一个rdd执行算子操作,去获取不

你可能感兴趣的:(大数据开发-Spark调优常用手段)