Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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
Java 在Spark中配置函数/lambda序列化_Java_Apache Spark_Lambda_Closures_Kryo - Fatal编程技术网

Java 在Spark中配置函数/lambda序列化

Java 在Spark中配置函数/lambda序列化,java,apache-spark,lambda,closures,kryo,Java,Apache Spark,Lambda,Closures,Kryo,如何将Spark配置为对lambdas使用KryoSerializer?还是我在Spark中发现了一个bug?我们对其他地方的数据序列化没有问题,只是在这些lambda中使用默认值而不是Kryo 代码如下: JavaPairRDD<String, IonValue> rdd; // provided IonSexp filterExpression; // provided Function<Tuple2<String, IonValue>, Boolean>

如何将Spark配置为对lambdas使用KryoSerializer?还是我在Spark中发现了一个bug?我们对其他地方的数据序列化没有问题,只是在这些lambda中使用默认值而不是Kryo

代码如下:

JavaPairRDD<String, IonValue> rdd; // provided
IonSexp filterExpression; // provided
Function<Tuple2<String, IonValue>, Boolean> filterFunc = record -> myCustomFilter(filterExpression, record);
rdd = rdd.filter(filterFunc);
注册人中的代码:

kryo.register(com.amazon.ion.IonSexp.class);
kryo.register(Class.forName("com.amazon.ion.impl.lite.IonSexpLite"));
如果我尝试用下面的代码手动序列化lambda

SerializationUtils.serialize(filterFunc);
由于
filtereexpression
不可序列化,因此它失败并出现与预期相同的错误。但是,以下代码有效:

sparkContext.env().serializer().newInstance().serialize(filterFunc, ClassTag$.MODULE$.apply(filterFunc.getClass()));
这也是我们所期望的,因为我们的Kryo装置能够处理这些对象


所以我的问题/困惑是,为什么Spark在我们已经清楚地将lambda配置为使用Kryo的情况下尝试用
org.apache.Spark.serializer.JavaSerializer
对它进行序列化?

在进一步挖掘之后,发现确实有一个不同的序列化程序用于闭包。由于Kryo的错误,闭包序列化程序硬编码为默认的

这个答案很好地解释了这一点:

不过,我能通过广播解决我的特殊问题

下面是我的代码现在的样子:

JavaSparkContext sparkContext; // provided
JavaPairRDD<String, IonValue> rdd; // provided
IonSexp filterExpression; // provided

Broadcast<IonSexp> filterExprBroadcast = sparkContext.broadcast(filterExpression);
rdd = rdd.filter(record -> myCustomFilter(filterExprBroadcast.value(), record));
filterExprBroadcast.destroy(false); // Only do this after an action is executed
JavaSparkContext sparkContext;//假如
javapairdd rdd;//假如
IonSexp filterExpression;//假如
广播filterExprBroadcast=sparkContext.Broadcast(filterExpression);
rdd=rdd.filter(记录->myCustomFilter(filterExprBroadcast.value(),记录));
filtereexprbroadcast.destroy(false);//仅在执行操作后执行此操作
广播的处理方式与RDD类似,因此它使用配置的Kryo序列化程序

sparkContext.env().serializer().newInstance().serialize(filterFunc, ClassTag$.MODULE$.apply(filterFunc.getClass()));
JavaSparkContext sparkContext; // provided
JavaPairRDD<String, IonValue> rdd; // provided
IonSexp filterExpression; // provided

Broadcast<IonSexp> filterExprBroadcast = sparkContext.broadcast(filterExpression);
rdd = rdd.filter(record -> myCustomFilter(filterExprBroadcast.value(), record));
filterExprBroadcast.destroy(false); // Only do this after an action is executed