spark优化可以从三个方面入手:
1、spark运行环境:存储与计算资源
2、优化RDD操作的使用方法
3、参数调优
1、运行环境的优化:
spark参数设置有三种方法,1、集群配置;2、提交命令设置;3、程序中设置
优先级是 3>2>1 (意思是如果都设置了,就执行3中的设置)
1)、防止不必要的jar包上传与分发
(当提交任务时,spark程序会将程序jar包和spark中bin目录下的jar包都提交到hdfs上,然后各个worker节点会去hdfs上拉取jar包然后执行)
1、将系统jar包上传到hdfs上,直接使用hdfs上的文件
1、在spark安装目录下运行:jar cvof spark-libs.jar -C jars/.
2、将spark-libs.jar 上传到hdfs上: bin/hadoop dfs -put spark-libs.jar /system/spark
3、在conf/defaults.conf中添加以下配置:
spark.yarn.archive=hdfs:///system/spark/spark-libs.jar
2、将应用程序jar包上传到hdfs上,防止重复分发
spark-submit \
--master \
yarn-cluster \
--class org.training.examples.WordCount \
hdfs://users/spark/jars/examples-1.0.jar
2)、提高数据本地性
提高数据本地性可以减少跨网络传输,数据本地行分为 PROCESS_LOCAL NODE_LOCAL RACK_LOCAL
提高数据本地性的方法:
1、计算和存储同节点部署
2、增加executor数目
3、增加数据副本数
4、调整spark.locality.wait(默认是3s),spark.locality.wait.process,spark.locality.wait.node,
spark.locality.wait.rack
3)、存储格式选择
列是存储和行式存储:列式存储相对于行式存储,采用了压缩格式,占用空间少,io量少,对于数据的读取不必要的数据列可以不进行读取
列式存储格式
ORC,源于Hive
Parpuet,跟MR和spark有良好的集成
4)、将spark程序运行在高配置的机器上
2、操作符的优化
1)、在经过过滤操作之后使用coalesce(num partitions)或者 repartition(num partitions)
coalesce 不经过洗牌,数据不均匀分布,效率高(推荐使用)
repartition 经过洗牌,数据均匀分布,效率低
2)、降低单条记录消耗的资源
在对数据看操作时,不要在map中对数据操作,使用mapPartition算子或者mapWith算子
3)、处理数据倾斜和任务倾斜
1、选择合理的Partition key
2、克服慢节点导致的任务运行缓慢(磁盘老化)
推测执行 : spark.speculation 设为true
3)、对key加随机数,分步执行
4)、对复用的数据进行缓存
5)、避免使用Cartesian
尽可能避免shuffle
如果可能,用reducebykey替换groupbykey
如果可能,用treeReduce替换reduce
输入输出value类型不同时,避免使用reducebykey:可以用aggregatebykey替换
注意:何时join不会产生shuffle
当 数据的hash 函数 和分区数相同时不会产生shuffle
6)、一个spark应用程序由多个job构成,如果job之间没有依赖关系,可以并行处理(充分利用资源)
启用FAIR调度器:spark.scheduler.mode=fair
将action相关操作放到单独线程中
3、作业参数调优
1)、设置合适的资源量
2)、设置合理的jvm参数
--num-executors NUM Number of executors to launch (Default: 2).
If dynamic allocation is enabled, the initial number of
executors will be at least NUM.--executor-cores NUM Number of cores per executor. (Default: 1 in YARN mode,
or all available cores on the worker in standalone mode) --executor-memory MEM Memory per executor (e.g. 1000M, 2G) (Default: 1G).