当前位置: 代码迷 >> java >> Spark / Java:不可序列化问题-Kryo序列化
  详细解决方案

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

热度:105   发布时间:2023-08-04 09:12:26.0

我对kryo序列化缺少什么?

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

当我尝试“使用”实例时,该实例是在Spark内部通过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();

由Class3引起的序列化错误

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实例作为变量的Composite对象。

因此,如果您提取class3.getId()的值,然后将其传递给地图转换,则无需在Kryo中注册Class3。

在上面包含我上面提到的Scala对象的示例中,它与Driver应用程序相同。

希望这可以帮助。

  相关解决方案