Spark 中一些常见的 troubleshooting

记录一些常见的 Spark 做业里的 troubleshooting。sql

1,shuffle reduce 端缓冲大小致使的 OOM

在 shuffle 过程当中,reduce 端在拉取 map 端的数据时,每一个 task 会有本身的 缓冲区用来存放每次拉取的数据,这个缓冲区默认是 48M。shell

若是 map 端产生的数据量很是大,而且 map 端的写入数据很是快,那么这时候 reduce 端的全部 task 的缓冲区可能会出现满负荷存储,每一个 task 的缓冲区都会被写满,那么会致使 task 在计算过程当中读取的数据量很大,但每一个 executor 在当前 JVM 进程中分配的内存是死的(0.2占比),这时候大量的 task 计算产生的对象极可能会撑爆内存,致使 OOM。网络

这时候咱们能够经过调小 reduce 端的缓冲区内存大小,让 task 多拉取几回,多些网络传输的性能消耗,但能够保证 reduce 端的内存够用。app

2,JVM 的 GC 致使 shuffle 文件拉取失败

Spark 做业中有时会出现的一种状况:shuffle file not found,仍是挺常见的。并且有的时候,出现这种状况之后,会从新去提交stage、task。从新执行一遍,发现就行了。没有这种错误了。函数

这是由于前一个 stage 在 shuffle 时候内存消耗太大,频繁的 gc,每当触发 gc 的时候,整个 JVM 进程都会中止做业。而在这个时候下一个 stage 的 executor 要拉取须要用的数据,这时候就会拉不到,这时候会尝试等待一会,再次拉取,有时候恰好等待时间后,前一个 stage 的 gc 结束,这时候就能拉到数据了。性能

这种状况能够调整这两个参数:spa

1,spark.shuffle.io.maxRetries shuffle 拉取失败后重试的次数,默认是 3 次;code

2,spark.shuffle.io.retryWait 每次重试拉取文件的时间间隔,默认是 5s;对象

3,Yarn 集群资源不足致使 application 直接失败

一个 Yarn 集群中可能已经跑了一个 spark 做业,这时候你又提交一个 spark 做业,两个 spark 做业设置的资源恰好等于或者稍小于整个集群的资源,这时候很容易致使跑不了第二个 spark 做业,由于 spark 做业跑起来以后耗费的资源颇有可能大于咱们在 shell 脚本里分配的资源。接口

为了防止这样的事情发生,有这几种方案:

1,在 J2EE 中作限制,同时只能提交一个 Spark 做业到 Yarn 集群上去执行,这样确保一个 Spark 做业的资源够用就行;

2,使用队列的方式执行 Spark 做业,保证每一个 Spark 做业分配的资源到最大化,确保每一个 Spark 做业在最短的时间内执行完毕;

4,序列化问题致使的报错

用 client 模式提交 Spark 做业时,本地打印的 log 中出现相似于 Serializable 之类的报错。这种报错是因为某类没有实现序列化接口致使的错误。

常见的须要序列化的地方有这两个:

1,算子函数汇总使用到外部的自定义类型的变量;

2,若是要将自定义的类型,做为 RDD 的元素类型,这个类型也要实现序列化接口;

5,Yarn-client 模式下致使网卡流量过大

生产环境下若是使用 Yarn-client 模式跑 Spark 做业,因为 driver 进程跑在本地设备上,大量的数据传输会致使本地设备的网卡流量十分的大。

因此生产环境要使用 Yarn-cluster 模式。

6,Yarn-cluster 模式下 JVM 内存溢出

有时候,运行了一些包含了 Spark sql 的 Spark 做业,可能会碰到在 Yarn-client 模式下正常运行,但在 Yarn-cluster 模式下,会报 JVM 的 PermGen(永久代)的内存溢出问题。

由于 Yarn-client 模式下,driver 是运行在本地设备上的,Spark 使用的 JVM 的 PermGen 的配置是本地的 spark class 文件,JVM 的永久带大小为 128M。但在 Yarn-cluster 模式下,drvier 是运行在 Yarn 集群的某个节点上的,默认的大小是 82M。

Spark sql 的内部有不少复杂的 SQL 语义解析,语法数转换等等,特别复杂。在这种状况下,若是 sql 写的比较发咋的话,会致使内存的消耗,对永久代的占用会比较大,容易超过 Yarn 集群上的设置的默认值。

解决方案:

spark-submit脚本中,加入如下配置便可:

--conf spark.driver.extraJavaOptions="-XX:PermSize=128M -XX:MaxPermSize=256M"

这个就设置了 driver 永久代的大小,默认是 128M,最大是 256M。那么,这样的话,就能够基本保证你的 Spark 做业不会出现上述的 yarn-cluster 模式致使的永久代内存溢出的问题。

相关文章
相关标签/搜索