Spark性能调优
- executor内存不足
- [用`UNION ALL`代替`UNION`](#用
UNION ALL
代替UNION
) - persist与耗时监控
executor内存不足
- 问题表现1:Container xx is running beyond physical memory limits. Current usage: xxx GB of x GB physical memory used; xx GB of x GB virtual memory used...
原因:这个报错显而易见,数据使用的内存超过了这个executor分配的内存 - 问题表现2:长时间的 Fail to get RpcResponse: Timeout,最后会报heartbeat心跳检测失败而任务失败
原因:实际上同样是因为内存不足,导致GC而超时,最终失败
解决:
1 首先可以尝试开大executor的内存分配
2 如果配置的内存无法满足数据内存,可以尝试:
2.1 增加大数据量位置的repartition数
scala
val allDf = sourceDf
.repartition(5000)
.flatMap(row => { }).toDF()
2.2 增加spark session的超时时间
scala
val ss = SparkSession.builder()
.config("spark.sql.shuffle.partitions", 1000)
.config("spark.driver.maxResultSize", "20g")
.config("hive.exec.dynamic.partition", true)
.config("hive.exec.dynamic.partition.mode", "nonstrict")
.config("hive.exec.parallel", true)
.config("mapred.max.split.size", 64000000)
.config("mapred.min.split.size.per.node", 64000000)
.config("mapred.min.split.size.per.rack", 64000000)
.config("hive.exec.reducers.bytes.per.reducer", 256000000)
.config("hive.exec.reducers.max", 2000)
.config("hive.merge.mapredfiles", true)
.config("hive.merge.smallfiles.avgsize", 128000000)
.config("hive.merge.size.per.task", 128000000)
.config("spark.yarn.executor.memoryOverhead", "10g")
.config("spark.network.timeout", 10000000) // 调大
.enableHiveSupport()
.getOrCreate()
用UNION ALL
代替UNION
UNION会默认对两个表的结果进行去重,如果没有去重的需要,就使用UNION ALL,速度会更快
persist与耗时监控
在主流程的对运算结果调用处persist,并打点进行耗时监控。而不是在运算方法内部persist,便于看清每一步的运算时间。