从Spark RDD读取一个Kryo文件

时间:2014-05-12 20:01:08

标签: apache-spark kryo

我是Spark&斯卡拉新手。

我需要阅读并分析Spark中的一个文件,它是用我的scala代码编写的,并使用Kryo序列化:

import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.Output

val kryo:Kryo = new Kryo()
val output:Output = new Output(new FileOutputStream("filename.ext",true))

//kryo.writeObject(output, feed) (tested both line)
kryo.writeClassAndObject(output, myScalaObject)

这是一个伪代码,用于创建一个文件,其中我的对象(myScalaObject)被序列化,这是一个复杂的对象。

该文件似乎写得很好,但是当我在Spark RDD中阅读它时我遇到了问题

Spark中的伪代码:

val conf = new SparkConf()
    .setMaster("local")
    .setAppName("My application")
    .set("spark.executor.memory", "1g")


conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
conf.set("spark.kryo.registrator", "myScalaObject")

val sc = new SparkContext(conf)

val file=sc.objectFile[myScalaObject]("filename.ext")

val counts = file.count()

当我尝试执行它时,我收到此错误:

org.apache.spark.SparkException:作业已中止:任务0.0:0失败1次(最近失败:异常失败:java.io.IOException:file:filename.ext不是SequenceFile)

可以在Spark中读取这种类型的文件吗?

如果无法使用此解决方案,那么在Spark中创建复杂的文件结构有什么好的解决方案?

谢谢

1 个答案:

答案 0 :(得分:2)

如果您想使用objectFile阅读,请使用saveAsObjectFile写出数据。

val myObjects: Seq[MyObject] = ...
val rddToSave = sc.parallelize(myObjects) // Or better yet: construct as RDD from the start.
rddToSave.saveAsObjectFile("/tmp/x")
val rddLoaded = sc.objectFile[MyObject]("/tmp/x")

或者,正如zsxwing所述,您可以创建文件名的RDD,并使用map来读取每个文件的内容。如果希望将每个文件读入单独的分区,请将文件名并行化为单独的分区:

def loadFiles(filenames: Seq[String]): RDD[Object] = {
  def load(filename: String): Object = {
    val input = new Input(new FileInputStream(filename))
    return kryo.readClassAndObject(input)
  }
  val partitions = filenames.length
  return sc.parallelize(filenames, partitions).map(load)
}
相关问题