Spark任务两个小问题笔记

今天在用spark处理数据的时候,遇到两个小问题,特此笔记一下。

两个问题都与网络交互有关,大致处理场景是,在driver端会提前获取组装一批数据,然后把这些数据发送executor端进行后续处理。

问题一:序列化异常

driver有一个case class类需要封装一些数据发送到executor上,原来都是scala的类,直接发送到executor上执行没问题,而且也没加序列化的注解,原因是因为scala会自动给函数方法序列化,因为这个类出现在函数中,所以也没事,但今天在这个类里面又加了一个java的bean,结果就出现了异常:

java.io.NotSerializableException

原因是新加的java bean没有序列化,所以导致了这个问题,scala的函数序列化可能并不是深度序列化,不会对类属性里面的类再次进行序列化,所以解决办法就是让这个java bean实现java的序列化接口:

Bean  implements Serializable

问题二:driver端发送的数据太大导致超过spark默认的传输限制

异常如下:

User class threw exception: java.util.concurrent.ExecutionException:
org.apache.spark.SparkException
: Job aborted due to stage failure: Serialized task 523:49 was 146289487 bytes, which exceeds max allowed: 
spark.rpc.message.maxSize (134217728 bytes).
Consider increasing spark.rpc.message.maxSize 
or using broadcast variables for large values.

从上面的异常提示,已经很明显了,就是默认driver向executor上提交一个任务,它的传输数据不能超过128M,如果超过就抛出上面的异常。

如何解决:

方法一:使用广播变量传输

方法二:调大spark.rpc.message.maxSize的值,默认是128M,我们可以根据需要进行适当调整

在使用spark-submit提交任务的时候,加上配置即可:

--conf "spark.rpc.message.maxSize=512" //代表每个分区允许发送的最大值是512M
Top