序列化RDD

我有一个RDD,我试图序列化,然后通过反序列化重建。 我试图看看Apache Spark中是否可行。

static JavaSparkContext sc = new JavaSparkContext(conf); static SerializerInstance si = SparkEnv.get().closureSerializer().newInstance(); static ClassTag<JavaRDD> tag = scala.reflect.ClassTag$.MODULE$.apply(JavaRDD.class); .. .. JavaRDD rdd = sc.textFile(logFile, 4); System.out.println("Element 1 " + rdd.first()); ByteBuffer bb= si.serialize(rdd, tag); JavaRDD rdd2 = si.deserialize(bb, Thread.currentThread().getContextClassLoader(),tag); System.out.println(rdd2.partitions().size()); System.out.println("Element 0 " + rdd2.first()); 

当我对新创建的RDD执行操作时,我在最后一行得到exception。 我序列化的方式类似于Spark内部的方式。

 Exception in thread "main" org.apache.spark.SparkException: RDD transformations and actions can only be invoked by the driver, not inside of other transformations; for example, rdd1.map(x => rdd2.values.count() * x) is invalid because the values transformation and count action cannot be performed inside of the rdd1.map transformation. For more information, see SPARK-5063. at org.apache.spark.rdd.RDD.sc(RDD.scala:87) at org.apache.spark.rdd.RDD.take(RDD.scala:1177) at org.apache.spark.rdd.RDD.first(RDD.scala:1189) at org.apache.spark.api.java.JavaRDDLike$class.first(JavaRDDLike.scala:477) at org.apache.spark.api.java.JavaRDD.first(JavaRDD.scala:32) at SimpleApp.sparkSend(SimpleApp.java:63) at SimpleApp.main(SimpleApp.java:91) 

RDD是在同一个进程中创建和加载的,所以我不明白这个错误是如何发生的。

我是这个警告信息的作者。

Spark不支持对通过反序列化创建的RDD副本执行操作和转换。 RDD是可序列化的,因此可以在执行程序中调用它们上的某些方法,但最终用户不应尝试手动执行RDD序列化。

当RDD被序列化时,它会丢失对创建它的SparkContext的引用,从而阻止使用它启动作业(参见此处 )。 在早期版本的Spark中,当Spark尝试访问私有的null RDD.sc字段时,您的代码将导致NullPointerException。

此错误消息以这种方式表达,因为用户在尝试执行rdd1.map { _ => rdd2.count() }等操作时经常遇到混淆NullPointerExceptions,这导致在执行程序计算机上的反序列化RDD上调用操作。 我没想到有人会尝试在驱动程序上手动序列化/反序列化他们的RDD,所以我可以看到这个错误消息可能会有些误导。