解析数以百万计的小型XML文件

时间:2015-09-16 18:42:49

标签: xml hadoop mapreduce hdfs

我有1000万个小型XML文件(300KB-500KB)。我在Mapreduce中使用Mahaout的XML输入格式来读取数据,我正在使用SAX Parser进行解析。但是处理速度非常慢。使用压缩(lzo)输入文件有助于提高性能吗?每个文件夹包含80-90k xml文件,当我启动进程时,它会为每个文件运行映射器。有没有办法减少映射器的数量?

2 个答案:

答案 0 :(得分:2)

Hadoop对大量小文件的效果不佳。它旨在处理一些非常大的文件。

压缩您的文件不会有帮助,因为您已经注意到问题是您的作业需要实例化大量容器来执行映射(每个文件一个)。实例化容器可能需要的时间超过处理输入所需的时间(以及内存和CPU等大量资源)。

我不熟悉Mahaout的输入格式,但在hadoop中有一个类可以最大限度地减少在一个Mapper中组合多个输入的问题。该类是CombineTextInputFormat。要使用XML,您可能需要创建自己的XMLInputFormat,扩展CombineFileInputFormat。

另一种替代方案,但更少的改进可能是在容器中重用JVM:reuse JVM in Hadoop mapreduce jobs

重新使用JVM安全创建每个JVM所需的时间,但您仍然需要为每个文件创建一个容器。

答案 1 :(得分:1)

您可以按照此article中引用的三种方法之一:

  1. Hadoop存档文件(HAR)
  2. 序列文件
  3. HBase的
  4. 我找到了article 1article 2,列出了多个解决方案(我从这些文章中删除了一些非通用的替代方案):

    1. 更改提取过程/间隔:更改源级别的逻辑以减少大量小文件并尝试生成少量大文件
    2. 批处理文件合并:当小文件不可避免时,文件合并是最常见的解决方案。使用此选项,您可以定期运行一个简单的合并MapReduce作业来读取文件夹中的所有小文件,并将它们重写为更少的更大文件
    3. 序列文件:当需要维护原始文件名时,一种非常常见的方法是使用序列文件。在此解决方案中,文件名作为密钥存储在序列文件中,文件内容存储为值
    4. HBase :不是将文件写入磁盘,而是将文件写入HBase内存存储区。
    5. 使用CombineFileInputFormat CombineFileInputFormat是Hadoop提供的抽象类,它在MapReduce读取时合并小文件。合并的文件不会持久保存到磁盘。相反,该过程会读取多个文件并“动态”合并它们以供单个地图任务使用。