Spark TroubleShooting——【笔记三】

本文总结了Spark在运行过程中遇到的问题及解决方案,包括:控制reduce端缓冲大小避免OOM,JVM GC引起的Shuffle文件拉取失败,序列化错误处理,算子函数返回NULL的解决办法,以及针对YARN模式下的内存和性能调优策略。
摘要由CSDN通过智能技术生成

Spark TroubleShooting——【笔记三】

[课程链接]——https://www.bilibili.com/video/av54322051?p=50

一、控制reduce端缓冲大小避免OOM

    在Shuffle过程中,reduce端task并不是等到map端task将其全部写入磁盘后再去拉取,而是map端写一点数据,reduce端的task就会拉取一小部分数据,然后立即进行后面的聚合、算子函数的使用等操作。
    reduce端task能够拉取多少数据,由reduce端拉取数据的缓冲区buffer来决定,因为拉取出来的数据都是先放在buffer中,然后再进行处理。buffer的默认大小为48MB。
    reduce端的task会一边拉取一边计算,不一定每次都会拉取慢48MB数据,可能大多数时候拉取一部分数据就处理掉了。
    虽说增大reduce端buffer可以减少拉取次数,但是有时map端数据量非常大,写出速度非常快,此时reduce端task在拉取时有可能全部达到自己buffer的最大值(48MB),再加上reduce端执行聚合函数代码,可能会导致内存溢出,即OOM。
    一旦出现reduce端OOM,则可以考虑减小reduce端拉取数据缓冲区的大小,这是典型的以空间换时间。要先保证任务能够运行,再考虑性能优化。

二、JVM GC导致的Shuffle文件拉取失败

    在Spark作业中,有时会出现shuffle file not found的错误,这是一个常见的报错,有时出现这种错误后,重新执行一遍,就不再有这种错误。
    出现上述问题的原因是由于Shuffle操作,后面Stage的task想要去上一个Stage的task所在的Executor拉取数据,结果对方正在GC,执行GC会导致Executor内的工作现场全部停止,如BlockManager,基于Netty的网络通信等,就会导致后面的task拉取数据时半天没有拉取到,就会报shuffle file not found的错误。
    可以通过调整reduce端拉取数据的重试次数和reduce端拉取数据的时间间隔这两个参数对Shuffle性能进行调优

//调节重试次数
SparkConf.set("spark.shuffle.io.maxRetries", "60")
//调节reduce端时间间隔
SparkConf.set("spark.shuffle.io.retryWait", "60s")

三、解决各种序列化导致的报错

    当Spark在运行过程中报错,而报错信息中含有Serializable等词汇,则可能是序列化问题导致的报错。
    序列化问题要注意以下三点:
        1.作为RDD的元素类型的自定义类,必须是可以序列化的;
        2.算子函数里可以使用的外部的自定义变量,必须是可以序列化的;
        3.不可以在RDD的元素类型、算子函数里使用第三方不支持序列化的类型,如Connection。

四、解决算子函数返回NULL导致的问题

    在一些算子函数里,需要有一个NULL值,但一些情况下我们不希望有返回值,此时我们如果过直接返回NULL,就会报错,如Scala.math(NULL)异常。
    如果遇到某些情况,不希望有返回值,则通过下述方式解决:
        1.返回特殊值,不返回NULL,如“-1”;
        2.在通过算子获取到一个RDD后,可以对这个RDD执行filter操作,进行数据过滤,将数值为-1的数据过滤掉;
        3.在使用完filter后,继续使用coalesce算子进行优化。

五、解决YARN-CLIENT模式导致的网卡流量激增问题

    在生产环境下,一般都是用YARN-cluster模式。

六、解决YARN-CLUSTER模式的JVM栈内存溢出无法执行的问题

    YARN-client模式下,Driver是运行在本地机器上的,Spark使用的是PermGen配置,是本地机器上的spark-class文件,JVM永久代的大小是128MB,这是没有问题的,但在YARN-cluster模式下,Driver运行在YARN集群的某个及诶单上,使用的是没有经过配置的默认设置,PermGen永久代的大小为82MB。
    在spark-submit中对相关参数进行设置

//设置Driver永久代大小,默认为128MB,最大256MB
--conf spark.driver.extraJavaOptions="-XX:PermGen=128M -XX:MaxPermSize=256M"

七、解决Spark SQL导致的JVM栈内存溢出

    当SparkSQL的sql语句有成百上千的or关键字时,就可能出现Driver端的JVM栈内存溢出。
    JVM栈内存溢出基本上就是由于调用的方法层级过多,产生了大量的、非常深的、超出了JVM栈深度限制的递归。
    此时建议将一条SQL语句拆分为多个SQL语句执行,每条SQL语句尽量保证在100个以内的子句。根据实际的生产环境试验,一条SQL语句的or关键字控制在100个以内,通常不会导致JVM栈内存溢出。

八、持久化与checkpoint的使用

    为了避免数据的丢失,可以选择对这个RDD进行checkpoint,也就是讲数据持久化一份到容错的文件系统上(如HDFS)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值