Java 在Spark中配置函数/lambda序列化
如何将Spark配置为对lambdas使用KryoSerializer?还是我在Spark中发现了一个bug?我们对其他地方的数据序列化没有问题,只是在这些lambda中使用默认值而不是Kryo 代码如下: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>
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