spark的调优分为以下部分:
资源优化
并行度优化
代码优化
数据本地化
内存优化
spark shuffle优化
调节executor堆外内存
解决数据倾斜
1.资源调优
1).搭建集群
在spark安装包的conf下spark-env.sh
SPARK_WORKER_CORES
SPARK_WORKER_MEMORY
SPARK_WORKER_INSTANCE
2).提交任务的时候
提交命令选项:(在提交Application的时候使用选项)
--executor-cores
--executor-memory
--total-executor-cores
配置信息:(在Application的代码中设置
在Spark-default.conf中设置)
spark.executor.cores
spark.executor.memory
spark.max.cores
2.并行度调优
1).降低读取文件的block ,sc.textFile(xxx)
2).sc.textFile(xxx,minnumPartitions)
3).sc.parallelize(xx,numpartitions)
4).sc.markRDD(xx,numpartitions)
5).sc.parallelizePairs(xx,numpartitions)
6).reduceByKey(xx,numpartitions)/join(xxx,numpartitions)
7).repartition(coalesce(numparititons,true))/coalesce
8).自定义分区器
9).spark.default.parallelism 生成的RDD的默认并行度
10).spark.sql.shuffle.partitions 默认200,sql执行有shuffle类的操作的分区数
11).SparkStreaming+Receiver spark.streaming.blockInterval=200ms
12).SparkStreming+Direct 读取的topic中的partition个数一致
3.代码调优
1).避免创建重复的RDD
2).复用同一个RDD
3).对多次使用的RDD进行持久化
4).尽量避免使用shuffle类的算子 广播变量+filter/map...
5).使用map-side预聚合的shuffle操作,尽量使用有combiner的shuffle类算子。
combiner概念:
在map端,每一个map task计算完毕后进行的局部聚合
combiner好处:
a) 降低shuffle write写磁盘的数据量。
b) 降低shuffle read拉取数据量的大小。
c) 降低reduce端聚合的次数。
6).尽量使用高性能的算子
使用reduceByKey替代groupByKey
使用mapPartitions替代map
使用foreachPartition替代foreach
filter后使用coalesce减少分区数
使用repartitionAndSortWithinPartitions替代repartition与sort类操作
使用repartition和coalesce算子操作分区
7).使用广播变量
8).使用Kryo优化序列化性能
9).优化数据结构
使用基本数据类型代替字符串
使用字符串代替对象
使用数组代替集合
10).使用高性能的库fastutil
4.数据本地化
数据本地化级别:
1) PROCESS_LOCAL:
task处理的数据在本Executor进程的内存中
2) NODE_LOCAL
task处理数据在本Executor所在的节点的磁盘中
task处理的数据在本Executor所在节点的其他Executor的内存中
3) NO_PREF
task处理的数据在数据库中
4) RACK_LOCAL
task处理的数据在同机架不同节点的Executor内存中
task处理的数据在同机架不同节点的磁盘上
5) ANY
task处理的数据在其他机架上
怎么调优:
• spark.locality.wait 3s
• spark.locality.wait.process
• spark.locality.wait.node
• spark.locality.wait.rack
5.内存调优
堆内存不足造成的影响:
1) 频繁的minor gc。
2) 老年代中大量的短生命周期的对象会导致full gc。
3) gc 多了就会影响Spark的性能和运行的速度。
怎么调?
1) 提高Executor总体内存的大小
2) 降低储存内存比例或者降低聚合内存比例
6.Spark Shuffle调优
spark.shuffle.file.buffer 32k
spark.reducer.MaxSizeFlight 48M
spark.shuffle.io.maxRetries 3
spark.shuffle.io.retryWait 5s
spark.shuffle.manager hash|sort
spark.shuffle.sort.bypassMergeThreshold 200----针对SortShuffle
spark.shuffle.consolidateFiles false----针对HashShuffle
7.调节Executor的堆外内存
节点之间连接默认等待时间:
--conf spark.core.connection.ack.wait.timeout=300
堆外内存调节:
yarn下:
--conf spark.yarn.executor.memoryOverhead=2048 单位M
standalone下:
--conf spark.executor.memoryOverhead=2048 单位M
8.解决数据倾斜
1).数据倾斜
HDFS
HDFS集群中某些节点数据非常多,某些节点数据非常少
Hive
某张表中某个key对应非常多的数据,某些key对应少量的数据
Spark
RDD中某个partition对应数据量非常多,某些partition对应数据量非常少
2).解决数据倾斜
a).使用Hive ETL预处理数据
场景:Spark要读取的数据源头是Hive表(有数据倾斜),业务是要经常操作这张表
解决:在Hive中先对这张表聚合,Spark频繁操作的是聚合后的结果
b).过滤少数倾斜的Key
场景:业务中去掉少数倾斜的Key反而使结果更正确
解决:sample抽样过滤掉这些倾斜的Key
c).提高shuffle并行度
前提:有多个Key不同
d).双重聚合
将相同的key随机加前缀聚合一次,然后将聚合后的结果去前缀再聚合一次
e).将reduce join转换成map join
彻底避免shuffle操作,避免数据倾斜
前提:两个RDD要join或者两张表要join,有一个RDD比较小或者一张表比较小
解决:将小的广播到Executor+Transformation类操作 避免shuffle
f).采样倾斜key并分拆join操作
膨胀N倍
g).使用随机前缀和扩容RDD进行join