在Spark中读取二进制InputStream会产生错误的结果

时间:2018-07-18 10:58:37

标签: java scala apache-spark

我正在设计一个Spark作业,以便:

  • 解析.tar.gz文件中的二进制文件
  • 使用从字节数组中提取的POJO创建数据框
  • 将它们存放在实木复合地板中

对于二进制文件的解析,我使用了一些旧的Java代码,该代码从字节数组中读取固定长度的字段。当我在笔记本电脑中将代码作为常规JVM进程的一部分执行时,此代码有效。

但是,当我将同一文件上传到HDFS并尝试从Spark读取文件时,由于我从没收到Java代码期望的字段,因此无法对字段进行固定长度的读取。

独立代码已成功使用:

// This is a local path in my laptop
val is = new GZIPInputStream(new FileInputStream(basepath + fileName))
val reader = new E4GTraceFileReader(is,fileName)

// Here I invoke the legacy Java code
// The result here is correct
val result = reader.readTraces()

火花作业:

val hdfs = FileSystem.get(new URI("hdfs://HDFS_IP_PORT/"), new Configuration())

val hdfsFiles = spark.sparkContext.parallelize(hdfs.listStatus(new Path("SOME_PATH")).map(_.getPath))

// Create Input Stream from each file in the folder
val inputStreamsRDD =  hdfsFiles.map(x =>{
  val hdfs = FileSystem.get(new URI("hdfs://HDFS_IP_PORT/"), new Configuration())
  (hdfs.open(x).getWrappedStream,x)
})

// Read the InputStream into a byte[]
val tracesRDD = inputStreamsRDD.flatMap(x => readTraceRecord(x._1,x._2)).map(flattenPOJO)

private def readTraceRecord(is : InputStream, fileName: Path) : List[E4GEventPacket] = {
 println(s"Starting to read ${fileName.getName}")
 val reader = new E4GTraceFileReader(is, fileName.getName)
 reader.readTraces().asScala.toList

}

我尝试同时使用FSDataInputStreamhdfs.open返回的hdfs.open(x).getWrappedStream,但没有得到预期的结果。 我不知道我是否应该在此处粘贴旧版Java代码,因为它有点冗长,但是我显然无法获得预期的字段。

您认为这里的问题是在Spark中从驱动程序到执行程序的序列化,这导致数据以某种方式被破坏了吗?

我尝试同时使用YARN和local [1],但得到的结果相同。

0 个答案:

没有答案