解析数百万个 XML 小文件

Parsing millions of small XML files

我有 1000 万个小 XML 文件 (300KB-500KB)。我在 Mapreduce 中使用 Mahaout 的 XML 输入格式来读取数据,我正在使用 SAX 解析器进行解析。但是处理非常 slow.will 使用输入文件的压缩 (lzo) 有助于提高性能?每个文件夹包含 80-90k xml 文件,当我开始处理时它 运行 映射器为每个 file.is 有什么方法可以减少映射器的数量?

Hadoop 不能很好地处理大量小文件。它旨在处理一些非常大的文件。

压缩文件无济于事,因为您已经注意到问题是您的工作需要实例化大量容器来执行映射(每个文件一个)。实例化容器花费的时间可能超过处理输入所需的时间(以及大量资源,如内存和 CPU)。

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

另一种改进较少的替代方法是在容器中重用 JVM:reuse JVM in Hadoop mapreduce jobs

重用 JVM 可以节省创建每个 JVM 所需的时间,但您仍然需要为每个文件创建一个容器。

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

  1. Hadoop 存档文件 (HAR)
  2. 序列文件
  3. HBase

我找到了 article 1 and article 2,其中列出了多个解决方案(我从这些文章中删除了一些非通用的替代方案):

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