Apache spark NotSerializableException:org.apache.hadoop.io.LongWritable
我知道这个问题已经被回答了很多次,但我尝试了所有的方法,但我没有找到解决办法。我有以下引发NotSerializableException的代码Apache spark NotSerializableException:org.apache.hadoop.io.LongWritable,apache-spark,Apache Spark,我知道这个问题已经被回答了很多次,但我尝试了所有的方法,但我没有找到解决办法。我有以下引发NotSerializableException的代码 val ids : Seq[Long] = ... ids.foreach{ id => sc.sequenceFile("file", classOf[LongWritable], classOf[MyWritable]).lookup(new LongWritable(id)) } 除了以下例外 Caused by: java.io.No
val ids : Seq[Long] = ...
ids.foreach{ id =>
sc.sequenceFile("file", classOf[LongWritable], classOf[MyWritable]).lookup(new LongWritable(id))
}
除了以下例外
Caused by: java.io.NotSerializableException: org.apache.hadoop.io.LongWritable
Serialization stack:
...
org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)
at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:84)
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:301)
创建SparkContext时,我会
val sparkConfig = new SparkConf().setAppName("...").setMaster("...")
sparkConfig.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
sparkConfig.registerKryoClasses(Array(classOf[BitString[_]], classOf[MinimalBitString], classOf[org.apache.hadoop.io.LongWritable]))
sparkConfig.set("spark.kryoserializer.classesToRegister", "org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text,org.apache.hadoop.io.LongWritable")
查看环境选项卡,我可以看到这些条目。但是,我不明白为什么
val rdd = sc
.sequenceFile("file", classOf[LongWritable], classOf[MyWritable])
rdd.cache()
LongWritables
simpleget
就足够了:
rdd.map{case (k, v) => k.get()}
关于自定义类,处理此问题是您的责任
import org.apache.spark.HashPartitioner
val numPartitions: Int = ???
val partitioned = rdd.partitionBy(new HashPartitioner(numPartitions))
查找
也必须线性搜索候选分区。一个RDD中有5000个均匀分布的密钥和10万个对象,这很可能意味着在整个RDD中重复搜索。您几乎没有避免这种情况的选择:
- 滤器
val idsSet = sc.broadcast(ids.toSet) rdd.filter{case (k, v) => idsSet.value.contains(k)}
- 加入
val idsRdd = sc.parallelize(ids).map((_, null)) idsRdd.join(rdd).map{case (k, (_, v)) => (k, v)}
- -但它不喜欢特别活跃的项目
val rdd = sc
.sequenceFile("file", classOf[LongWritable], classOf[MyWritable])
rdd.cache()
LongWritables
simpleget
就足够了:
rdd.map{case (k, v) => k.get()}
关于自定义类,处理此问题是您的责任
import org.apache.spark.HashPartitioner
val numPartitions: Int = ???
val partitioned = rdd.partitionBy(new HashPartitioner(numPartitions))
查找
也必须线性搜索候选分区。一个RDD中有5000个均匀分布的密钥和10万个对象,这很可能意味着在整个RDD中重复搜索。您几乎没有避免这种情况的选择:
- 滤器
val idsSet = sc.broadcast(ids.toSet) rdd.filter{case (k, v) => idsSet.value.contains(k)}
- 加入
val idsRdd = sc.parallelize(ids).map((_, null)) idsRdd.join(rdd).map{case (k, (_, v)) => (k, v)}
- -但它不喜欢特别活跃的项目
我是apache spark的新手,但我试图解决您的问题,请对其进行评估,如果它能帮助您解决序列化问题,这是因为spark-hadoop LongWritable和其他可写文件没有序列化
val temp_rdd = sc.parallelize(ids.map(id =>
sc.sequenceFile("file", classOf[LongWritable], classOf[LongWritable]).toArray.toSeq
)).flatMap(identity)
ids.foreach(id =>temp_rdd.lookup(new LongWritable(id)))
我是apache spark的新手,但我试图解决您的问题,请对其进行评估,如果它能帮助您解决序列化问题,这是因为spark-hadoop LongWritable和其他可写文件没有序列化
val temp_rdd = sc.parallelize(ids.map(id =>
sc.sequenceFile("file", classOf[LongWritable], classOf[LongWritable]).toArray.toSeq
)).flatMap(identity)
ids.foreach(id =>temp_rdd.lookup(new LongWritable(id)))
我不太确定您想要完成什么。为什么不将其转换为常规rdd,然后进行查找?性能方面我不确定。请参阅。关于性能,重新加载同一个文件是非常糟糕的:)此外,10M中有5K个条目,您可能会接触到几乎所有分区,因此简单的过滤器可能是更好的选择。还有一件事——为了高效查找,您需要一个分区器。如果没有它,它只是对所有分区的线性搜索。我不太确定您要完成什么。为什么不将其转换为常规rdd,然后进行查找?从性能角度看,我不确定。请参阅。关于性能,重新加载同一个文件是非常糟糕的:)此外,10M中有5K个条目,您可能会接触到几乎所有分区,因此简单的过滤器可能是更好的选择。还有一件事——为了高效查找,您需要一个分区器。没有它,它只是对所有分区的线性搜索。谢谢你的提示!我现在使用LevelDB和Spark将LevelDB集成到我的应用程序中,这样可以大大缩短查询时间!我还尝试了IndexedRDD,如果数据都保存在内存中,它会非常有效,这是我想要避免的。谢谢你的提示!我现在使用LevelDB和Spark将LevelDB集成到我的应用程序中,这样可以大大缩短查询时间!我还尝试了IndexedRDD,如果数据都保存在内存中,它会非常有效,这是我想要避免的。