Spark/Java:不可序列化的问题 - Kryo 序列化



关于 kryo 序列化,我缺少什么?

Class1 和Class3 不是 java 可序列化的类(没有默认构造函数,也没有 getter 和 setter)

当我尝试"使用"一个在 Spark 上下文中创建的实例时,无论我是否将 Classe3 注册为 Kryo 类,我都会遇到序列化问题。

工作正常:

Dataset<Class1> ds = spark.createDataset(classes, Encoders.kryo(Class1.class));
Dataset<String> df = df.map((MapFunction<Class1, String>) class1 -> class1.getName(), Encoders.STRING());
df.show();

类 3 导致的序列化错误

spark = SparkSession
.builder()
.master("local[*]")
.config(new SparkConf().registerKryoClasses(new Class[] {Class3.class}))
.appName("spark_test")
.getOrCreate();
Class3 class3 = Class3.getInstance();
Dataset<Class1> ds = spark.createDataset(classes, Encoders.kryo(Class1.class));
Dataset<String> df = df.map((MapFunction<Class1, String>) class1 -> class1.getName() + "-" class3.getId(), Encoders.STRING());
df.show();

总结评论中发生的讨论以形成答案 - 尝试调用转换时,Spark 驱动程序必须为该转换中的代码创建闭包并将其交付给负责运行该转换的执行程序。在您的情况下,代码行Class3 class3 = Class3.getInstance();是 Scala 对象的一部分,它包含 Spark 上下文的创建和使用以达到某个结果,即驱动程序应用程序。因此,当您尝试在映射转换中传递class3时,驱动程序正在尝试序列化封闭的 Scala 对象。除非您实现可序列化,否则此 scala 对象本身不可序列化,因此您会遇到序列化问题。

Re:Kryo 序列化 - 因为您已经向 Kryo 注册了 Class3,所以它将帮助您序列化 Class3 实例,但它不会序列化将 Class3 实例作为变量的复合对象。

因此,如果您提取class3.getId()的值,然后将其传递给您的映射转换,则不需要向 Kryo 注册 Class3。

在您的示例中,我上面提到的封闭 Scala 对象与驱动程序应用程序相同。

希望这有帮助。

相关内容

  • 没有找到相关文章

最新更新