我正在设计一个Spark作业,以便:
对于二进制文件的解析,我使用了一些旧的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
}
我尝试同时使用FSDataInputStream
和hdfs.open
返回的hdfs.open(x).getWrappedStream
,但没有得到预期的结果。
我不知道我是否应该在此处粘贴旧版Java代码,因为它有点冗长,但是我显然无法获得预期的字段。
您认为这里的问题是在Spark中从驱动程序到执行程序的序列化,这导致数据以某种方式被破坏了吗?
我尝试同时使用YARN和local [1],但得到的结果相同。