spark-troubleshooting-常用问题解决

来源:互联网 发布:csgo显示网络数据命令 编辑:程序博客网 时间:2024/06/05 11:12

现象:
Failed to get broadcast_9_piece0 of broadcast_9
解决:
–conf spark.cleaner.ttl=120000

现象:
**1. missing output location
org.apache.spark.shuffle.MetadataFetchFailedException:
Missing an output location for shuffle 0
2. shuffle fetch faild
org.apache.spark.shuffle.FetchFailedException:
Failed to connect to spark047215/192.168.47.215:50268**

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

解决:
提高executor内存即可,同时增加每个executor的cpu,这样不会减少task并行度。
● spark.executor.memory 15G
● spark.executor.cores 3
● spark.cores.max 21

现象:
1. executor lost
WARN TaskSetManager: Lost task 1.0 in stage 0.0 (TID 1, aa.local):
ExecutorLostFailure (executor lost)
2**. task lost**
WARN TaskSetManager: Lost task 69.2 in stage 7.0 (TID 1145, 192.168.47.217):
java.io.IOException: Connection from /192.168.47.217:55483 closed

  1. 各种timeout
    java.util.concurrent.TimeoutException: Futures timed out after [120 second]

ERROR TransportChannelHandler: Connection to /192.168.47.212:35409
has been quiet for 120000 ms while there are outstanding requests.
Assuming connection is dead; please adjust spark.network.
timeout if this is wrong

解决:
由网络或者gc引起,worker或executor没有接收到executor或task的心跳反馈。
提高 spark.network.timeout 的值,根据情况改成300(5min)或更高。
默认为 120(120s),配置所有网络传输的延时,如果没有主动设置以下参数,默认覆盖其属性
● spark.core.connection.ack.wait.timeout
● spark.akka.timeout
● spark.storage.blockManagerSlaveTimeoutMs
● spark.shuffle.io.connectionTimeout
● spark.rpc.askTimeout or spark.rpc.lookupTimeout

现象:
**org.apache.spark.SparkException: Job aborted due to stage failure:
Task not serializable: java.io.NotSerializableException: …**

解决:
1. 将所有调用到的外部变量直接放入到以上所说的这些算子中,这种情况最好使用foreachPartition减少创建变量的消耗。
2. 将需要使用的外部变量包括sparkConf,SparkContext,都用 @transient进行注解,表示这些变量不需要被序列化
3. 将外部变量放到某个class中对类进行序列化。

现象:
**Caused by: org.apache.spark.SparkException:
Job aborted due to stage failure: Total size of serialized
results of 374 tasks (1026.0 MB) is bigger than
spark.driver.maxResultSize (1024.0 MB)**

解决:
spark.driver.maxResultSize默认大小为1G 每个Spark action(如collect)所有分区的序列化结果的总大小限制,简而言之就是executor给driver返回的结果过大,报这个错说明需要提高这个值或者避免使用类似的方法,比如countByValue,countByKey等。
将值调大即可
spark.driver.maxResultSize 2g

现象:
**WARN TaskSetManager: Stage 198 contains a task of very large size (5953 KB). The maximum recommended task size is 100 KB.
这个WARN可能还会导致ERROR
Caused by: java.lang.RuntimeException: Failed to commit task
Caused by: org.apache.spark.executor.CommitDeniedException: attempt_201603251514_0218_m_000245_0: Not committed because the driver did not authorize commit**

解决:

如果你比较了解spark中的stage是如何划分的,这个问题就比较简单了。 一个Stage中包含的task过大,一般由于你的transform过程太长,因此driver给executor分发的task就会变的很大。
所以解决这个问题我们可以通过拆分stage解决。也就是在执行过程中调用cache.count缓存一些中间数据从而切断过长的stage。

现象:
部分executor并没有在执行任务

解决:
(1) 任务partition数过少,
要知道每个partition只会在一个task上执行任务。改变分区数,可以通过 repartition 方法,即使这样,在repartition 前还是要从数据源读取数据,此时(读入数据时)的并发度根据不同的数据源受到不同限制,常用的大概有以下几种:
hdfs - block数就是partition数
mysql - 按读入时的分区规则分partition
es - 分区数即为 es 的 分片数(shard)

(2) 数据本地性的副作用
taskSetManager在分发任务之前会先计算数据本地性,优先级依次是:
process(同一个executor) -> node_local(同一个节点) -> rack_local(同一个机架) -> any(任何节点)
Spark会优先执行高优先级的任务,任务完成的速度很快(小于设置的spark.locality.wait时间),则数据本地性下一级别的任务则一直不会启动,这就是Spark的延时调度机制。
举个极端例子:运行一个count任务,如果数据全都堆积在某一台节点上,那将只会有这台机器在长期计算任务,集群中的其他机器则会处于等待状态(等待本地性降级)而不执行任务,造成了大量的资源浪费。
判断的公式为:
curTime – lastLaunchTime >= localityWaits(currentLocalityIndex)
其中 curTime 为系统当前时间,lastLaunchTime 为在某优先级下最后一次启动task的时间
如果满足这个条件则会进入下一个优先级的时间判断,直到 any,不满足则分配当前优先级的任务。
数据本地性任务分配的源码在 taskSetManager.scala 。
如果存在大量executor处于等待状态,可以降低以下参数的值(也可以设置为0),默认都是3s。
spark.locality.wait
spark.locality.wait.process
spark.locality.wait.node
spark.locality.wait.rack

现象:spark task 连续重试失败
有可能哪台worker节点出现了故障,task执行失败后会在该 executor 上不断重试,达到最大重试次数后会导致整个 application 执行失败

解决:
我们可以设置失败黑名单(task在该节点运行失败后会换节点重试),可以看到在源码中默认设置的是 0,
private val EXECUTOR_TASK_BLACKLIST_TIMEOUT =
conf.getLong(“spark.scheduler.executorTaskBlacklistTime”, 0L)
在 spark-default.sh 中设置
spark.scheduler.executorTaskBlacklistTime 30000
当 task 在该 executor 运行失败后会在其它 executor 中启动,同时此 executor 会进入黑名单30s(不会分发任务到该executor)

现象:
如果你的任务shuffle量特别大,同时rdd缓存比较少

解决:
spark.storage.memoryFraction - 分配给rdd缓存的比例,默认为0.6(60%),如果缓存的数据较少可以降低该值。
spark.shuffle.memoryFraction - 分配给shuffle数据的内存比例,默认为0.2(20%)
剩下的20%内存空间则是分配给代码生成对象等。
如果任务运行缓慢,jvm进行频繁gc或者内存空间不足,或者可以降低上述的两个值。
“spark.rdd.compress”,”true” - 默认为false,压缩序列化的RDD分区,消耗一些cpu减少空间的使用

现象:
mysql读取慢,需要并发度优化

解决:
spark.default.parallelism
发生shuffle时的并行度,在standalone模式下的数量默认为core的个数,也可手动调整,数量设置太大会造成很多小任务,增加启动任务的开销,太小,运行大数据量的任务时速度缓慢。

spark.sql.shuffle.partitions
sql聚合操作(发生shuffle)时的并行度,默认为200,如果该值太小会导致OOM,executor丢失,任务执行时间过长的问题
相同的两个任务:
spark.sql.shuffle.partitions=300:
spark.sql.shuffle.partitions=500:
速度变快主要是大量的减少了gc的时间。
但是设置过大会造成性能恶化,过多的碎片task会造成大量无谓的启动关闭task开销,还有可能导致某些task hang住无法执行。

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

现象:
数据倾斜

解决:
数据倾斜大多数情况是由于大量的无效数据引起,比如null或者”“,也有可能是一些异常数据,比如统计用户登录情况时,出现某用户登录过千万次的情况,无效数据在计算前需要过滤掉。
数据处理有一个原则,多使用filter,这样你真正需要分析的数据量就越少,处理速度就越快。
sqlContext.sql(“…where col is not null and col != ””)

其他解决方案 请阅读我的另一篇文章:
http://blog.csdn.net/qq_16038125/article/details/73908597

原创粉丝点击