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 对象的示例中,与驱动程序应用程序相同。
希望对您有所帮助。
关于 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 对象的示例中,与驱动程序应用程序相同。
希望对您有所帮助。