Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spark/Java:不可序列化问题-Kryo序列化_Java_Apache Spark_Serialization_Apache Spark Sql_Kryo - Fatal编程技术网

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

Spark/Java:不可序列化问题-Kryo序列化,java,apache-spark,serialization,apache-spark-sql,kryo,Java,Apache Spark,Serialization,Apache Spark Sql,Kryo,关于kryo系列化,我遗漏了什么 Class1和Class3不是java可序列化类(没有默认构造函数,也没有getter和setter) 当我尝试“使用”一个实例时,它是在Spark内部的Spark上下文中创建的,无论我是否将Classe3注册为Kryo类,我都会遇到一个序列化问题 工作正常: Dataset<Class1> ds = spark.createDataset(classes, Encoders.kryo(Class1.class)); Dataset<Stri

关于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();
Dataset ds=spark.createDataset(class,Encoders.kryo(Class1.class));
Dataset df=df.map((MapFunction)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=SparkSession
.builder()
.master(“本地[*]”)
.config(新的SparkConf().registerKryoClasses(新类[]{Class3.Class}))
.appName(“火花试验”)
.getOrCreate();
Class3 Class3=Class3.getInstance();
Dataset ds=spark.createDataset(类,Encoders.kryo(Class1.class));
数据集df=df.map((MapFunction)class1->class1.getName()+“-”class3.getId(),Encoders.STRING());
df.show();

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

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

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

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


希望这有帮助。

你能尝试传递
class3.getId()的值,而不是在map中调用这个函数吗?@Amit,我不能。这只是一个理解为什么它不起作用的例子。在实际代码中,我可能需要访问这个类3中的许多不同属性。我相信您发布的任何代码都是Scala对象或类的一部分。我认为,当您尝试访问class3.getId时,spark试图将scala对象本身序列化为
class3 class3=class3.getInstance()
是该Scala类或对象的成员变量。因此,我要求您检查在传递class3.getId的值时会发生什么。@Amit,如果我传递class3.getId()的值,或者即使我在函数内部调用class3.getInstance().getId(),它也可以正常工作。对于这两种情况,我都不需要将Class3注册为Kryo classKryo将序列化Class3的对象。然而,正如我在前面的评论中提到的,当Spark driver发送闭包以在执行器上执行时,它将必须序列化Scala对象,该对象具有您的代码本身,正如您将其声明为成员变量一样。通常,在映射(或转换)中编写的任何代码都需要通过网络序列化发送给执行器。希望这对你有帮助。如果这解释了你的疑问,我可以根据这个写下我的答案,然后你可以标记这个问题的答案。