一、常见问题

1、org.apache.spark.shuffle.FetchFailedException

当前的配置为每个 executor 使用 1cpu,5GRAM,启动了 20 个 executor,

      这种问题一般发生在有大量 shuffle 操作的时候,task 不断的 failed,然后又重执行,一直循环下去,非常的耗时。

解决方案:

一般遇到这种问题提高 executor 内存即可,同时增加每个 executor 的 cpu,这样不会减少task 并行度。

spark.executor.memory 15G

spark.executor.cores 3

spark.cores.max 21

2、倾斜问题:

大多数任务都完成了,还有那么一两个任务怎么都跑不完或者跑的很慢。

分为数据倾斜和 task 倾斜两种。

数据倾斜:

数据倾斜大多数情况是由于大量 null 值或者""引起,在计算前过滤掉这些数据既可。

例如:sqlContext.sql("...where col is not null and col != ''")

任务倾斜:

task 倾斜原因比较多,网络 io,cpu,mem 都有可能造成这个节点上的任务执行缓慢,可以去看该节点的性能监控分析原因。

或者可以开启 spark 的推测机制开启推测机制后如果某一台机器的几个 task 特别慢,推测机制会将任务分配到其他机器执行,最后 Spark 会选取最快的作为最终结果

spark.speculation true

spark.speculation.interval 100 - 检测周期,单位毫秒;

spark.speculation.quantile 0.75 - 完成 task 的百分比时启动推测

spark.speculation.multiplier 1.5 - 比其他的慢多少倍时启动推测。

3、内存溢出。

内存不够,数据太多就会抛出 OOM 的 Exeception。

增加 executor 内存总量,也就是说增加 spark.executor.memory 的值

增加任务并行度(大任务就被分成小任务了),参考下面优化并行度的方法

二、优化

1、内存分配方面

如果执行的任务shuffle量特别大,rdd缓存的数据比较少,可以减少分配给rdd缓存的比例和增大分配给shuffle数据的内存比例。

spark.storage.memoryFraction

spark.shuffle.memoryFraction

内存空间不足:

如果任务运行缓慢, jvm 进行频繁 gc 或者内存空间不足,可以降低上述的两个值。

"spark.rdd.compress","true" - 默认为 false,压缩序列化的 RDD 分区,消耗一些cpu 减少空间的使用

如果数据只使用一次,不要采用 cache 操作,因为并不会提高运行速度,还会造成内存浪费。

2、并行度,即数据分片

spark.default.parallelism    发生 shuffle 时的并行度

数量设置太大会造成很多小任务,增加启动任务的开销,太小,内存压力大,运行大量数据的任务时速度缓慢。

spark.sql.shuffle.partitions  sql 聚合操作(发生 shuffle)时的并行度,默认为 200,如果任务运行缓慢增加这个值


修改 map 阶段并行度主要是在代码中使用 rdd.repartition(partitionNum)来操作。