Spark task not serializable错误的分析和处理

xiaoxiao2021-02-28  66

在编写代码Spark应用时出现以上的问题,最后发现是因为Dataset<Row>的foreach方法中传入的参数ForeachFunction<Row>引起的,代码如下: projectDataSourceDFFromMySQL.foreach(new ForeachFunction<Row>() { private static final long serialVersionUID = 4222182685492143838L; public void call(Row t) throws Exception { String id = t.getString(0); System.out.println(id); } }); 我分析原因是:这里的实现了接口ForeachFunction的内部类在运行的时候Master会将其序列化传给Slave,因此这个类必须要序列化,但是内部类序列化的时候需要其所寄宿的外部类的对象,而我这个外部类并没有实现Serializable接口,因此无法序列化,则会报上边的错误,将外部类实现Serializable接口后则问题解决。 按照上边的分析,如果我单独将ForeachFunction接口实现成一个类是不是就不需要让宿主类实现Serializable接口了呢?于是实现了一个类,代码如图: public class ForeachFunTest implements ForeachFunction<Row> { private static final long serialVersionUID = -4892194648703458595L; public void call(Row t) throws Exception { String id = t.getString(0); System.out.println(id); } } 然后foreach的地方改为: projectDataSourceDFFromMySQL.foreach(new ForeachFunTest()); 的确,这时之前的宿主类就不需要实现Serializable接口了。由此可以得出一个结论,如果这个ForeachFunction中引入的所有的变量都必须是可序列化的,而且变量对应的类也必须放在Slave的类加载器下,因为在Slave那端反序列化的时候要用到这些类的Class信息。当然了,报这个错误也有其他原因,我这里叙述的算是其中的一个。也不是啥高大上的知识点,希望能解决一些人的疑惑,抛砖引玉。
转载请注明原文地址: https://www.6miu.com/read-96343.html

最新回复(0)