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

Spark/Java : Not serializable issue - Kryo serialization

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

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

当我尝试 "use" 一个在 Spark 上下文之外创建的实例时,在 Spark 内部,我遇到了一个序列化问题,无论我是否将 Classe3 注册为 Kryo class。

工作正常:

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 对象的示例中,与驱动程序应用程序相同。

希望对您有所帮助。