我是一名新的Spark用户,我正在尝试处理位于HDFS文件系统上的大型XML文件集。一个"开发"大约有150k文件,总共大约28GB。一台机器的集群(实际上是一台虚拟机)。
文件被组织成HDFS中的目录结构,使得在单个父目录下有大约一百个子目录。每个孩子"目录包含几百到几千个XML文件之间的任何内容。
我的任务是解析每个XML文件,使用XPath表达式提取一些值,并将结果保存到HBase。我试图用Apache Spark做到这一点,我没有太多运气。我的问题似乎是Spark API和RDD工作方式的结合。在这一点上,分享一些伪代码以表达我想要做的事情可能是谨慎的:
RDD[String] filePaths = getAllFilePaths()
RDD[Map<String,String>] parsedFiles = filePaths.map((filePath) => {
// Load the file denoted by filePath
// Parse the file and apply XPath expressions
})
// After calling map() above, I should have an RDD[Map<String,String>] where
// the map is keyed by a "label" for an xpath expression, and the
// corresponding value is the result of the expression applied to the file
因此,将我写给HBase的部分折扣一下,让我们重点关注上述内容。我无法从RDD map()调用中加载文件。
我尝试了很多不同的方法,但都失败了:
SparkContext.textFile("/my/path")
加载文件失败,因为SparkContext
不可序列化FileSystem.open(path)
,其中FileSystem
在RDD之外实例化失败,因为FileSystem
不可序列化FileSystem.open(path)
调用,FileSystem
在中实例化,RDD失败,因为程序用尽了文件句柄。 其他方法包括尝试使用SparkContext.wholeTextFiles("/my/path/*")
,因此我不必在map()调用中执行文件加载,因为程序内存不足而失败。这可能是因为它急切地加载文件。
有没有人在自己的工作中尝试过类似的东西,如果有的话,你使用了什么方法?
答案 0 :(得分:-1)
尝试使用通配符来读取整个目录。
val errorCount = sc.textFile("hdfs://some-directory/*")
实际上,spark可以读取整个hfs目录,引用spark documentation
所有Spark的基于文件的输入方法,包括textFile,都支持 在目录,压缩文件和通配符上运行。对于 例如,您可以使用
textFile("/my/directory")
,textFile("/my/directory/*.txt")
和textFile("/my/directory/*.gz")
。