我有一个大(> 500m行)的CSV文件。 CSV文件中的每一行都包含指向HDFS上的二进制文件的路径。我想使用Spark读取每个文件,进行处理,然后将结果写到另一个CSV文件或表中。
在驱动程序中执行此操作非常简单,下面的代码即可完成工作
val hdfsFilePathList = // read paths from CSV, collect into list
hdfsFilePathList.map( pathToHdfsFile => {
sqlContext.sparkContext.binaryFiles(pathToHdfsFile).mapPartitions {
functionToProcessBinaryFiles(_)
}
})
与此有关的主要问题是驱动程序正在做太多的工作。我想将binaryFiles
完成的工作分发给执行者。我找到了一些有希望的示例,我认为这些示例可以使我从执行程序访问sparkContext:
Use SparkContext hadoop configuration within RDD methods/closures, like foreachPartition
但是它们似乎没有按照我认为的方式工作。我希望以下方法能起作用:
import java.io.{ObjectInputStream, ObjectOutputStream}
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.conf.Configuration
class ConfigSerDeser(var conf: Configuration) extends Serializable {
def this() {
this(new Configuration())
}
def get(): Configuration = conf
private def writeObject (out: java.io.ObjectOutputStream): Unit = {
conf.write(out)
}
private def readObject (in: java.io.ObjectInputStream): Unit = {
conf = new Configuration()
conf.readFields(in)
}
private def readObjectNoData(): Unit = {
conf = new Configuration()
}
}
val serConf = new ConfigSerDeser(sc.hadoopConfiguration)
val mappedIn = inputDf.map( row => {
serConf.get()
})
但是它失败并显示KryoException: java.util.ConcurrentModificationException
执行者是否可以直接访问HDFS文件或HDFS文件系统?或者,是否存在一种有效的方法来读取HDFS / S3上的数百万个二进制文件并使用Spark处理它们?
答案 0 :(得分:0)
有一个类似的用例,我试图做同样的事情,但是意识到 SparkSession或SparkContext不可序列化,因此无法从执行程序访问。