【发布时间】:2015-11-19 18:49:46
【问题描述】:
我是新的 Spark 用户,我正在尝试处理位于 HDFS 文件系统上的大量 XML 文件集。在 1 台机器(实际上是 VM)的“开发”集群上大约有 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() 调用中加载文件。
我尝试了很多不同的方法,但都失败了:
- 使用call 到
SparkContext.textFile("/my/path")加载文件失败,因为SparkContext不可序列化 - 使用 Hadoop API 中的 call 到
FileSystem.open(path),其中FileSystem在 RDD 外部实例化失败,因为FileSystem不可序列化 - 使用从 Hadoop API 调用
FileSystem.open(path),其中FileSystem在内部被实例化,RDD 失败,因为程序用完了文件句柄。
替代方法包括尝试使用SparkContext.wholeTextFiles("/my/path/*"),因此我不必从 map() 调用中加载文件,因为程序内存不足而失败。这大概是因为它急切地加载文件。
有没有人在他们自己的工作中尝试过类似的事情,如果有,您使用了什么方法?
【问题讨论】:
-
我认为
wholeTextFiles是要走的路。只需添加更多内存即可。 -
感谢您的评论。不幸的是,我没有 28GB 的内存可以玩。一旦我收到一个更大的文件集,比如 500GB 而不是 28GB,采用这种方法就会崩溃。
-
不,
wholeTextFiles只需要足够的内存来加载最大的文件。如果您获得更多文件,那很好,您将不需要更多内存。 (每个执行线程一次加载 1 个文件。您还可以限制执行线程的数量,因此每个线程有更多的内存。)
标签: java scala hadoop apache-spark