2

我是 Hadoop MapReduce 的新手(准确地说是 4 天),我被要求在集群上执行分布式 XML 解析。根据我在 Internet 上的(重新)搜索,使用 Mahout 的 XmlInputFormat 应该相当容易,但我的任务是确保系统适用于巨大的 (~5TB) XML 文件。

据我所知,发送到映射器的文件拆分不能大于 hdfs 块大小(或每个作业块大小)。[如果我错了,请纠正我]。

我面临的问题是一些 XML 元素很大(~200MB),一些很小(~1MB)

所以我的问题是:当 XmlInputFormat 创建的 XML 元素块大于块大小时会发生什么?它会将整个大文件(比如 200MB)发送到映射器还是将元素分成三个分割(64+64+64+8)发送?

我目前无法访问公司的 hadoop 集群(直到某个时候才能访问),所以我无法进行测试并找出答案。请帮帮我。

4

1 回答 1

6

所以要澄清一些事情:

Mahout 的 XMLInputFormat 将处理 XML 文件并提取两个配置的开始/结束标记之间的 XML。因此,如果您的 XML 如下所示:

<main>
  <person>
    <name>Bob</name>
    <dob>1970/01/01</dob>
  </person>
</main>

并且您已将开始/结束标签配置为<person>and </person>,那么您的映射器将通过以下<LongWritable, Text>对传递给它的 map 方法:

LongWritable: 10
Text: "<person>\n    <name>Bob</name>\n    <dob>1970/01/01</dob>\n  </person>"

然后,您在映射器中如何处理这些数据取决于您。

关于拆分、XmlInputFormat扩展TextInputFormat,因此如果您的输入文件是可拆分的(即未压缩或使用可拆分的编解码器(如 snappy)压缩),则该文件将由一个或多个映射器处理,如下所示:

  1. 如果输入文件大小(比如 48 MB)小于 HDFS 中的单个块(比如 64MB),并且您没有配置最小/最大拆分大小属性,那么您将获得一个单独的映射器来处理文件
  2. 与上面一样,但是您将最大拆分大小配置为 10MB ( mapred.max.split.size=10485760),那么您将获得 5 个地图任务来处理文件
  3. 如果文件大于块大小,那么您将获得每个块的映射任务,或者如果配置了最大拆分大小,则文件的每个部分按该拆分大小划分的映射

当文件被分割成这些块或分割大小的块时,XmlInputFormat 将寻找块/分割边界的字节地址/偏移量,然后向前扫描,直到找到配置的 XML 开始标记或到达块的字节地址/分割边界。如果找到开始标签,它将使用数据,直到找到结束标签(或文件结尾)。如果它找到结束标记,一条记录将传递给您的映射器,否则您的映射器将不会收到任何输入。需要强调的是,当试图找到结束标签时,地图可能会扫描超过块/拆分的末尾,但只有在找到开始标签时才会这样做,否则扫描会在块/拆分的末尾停止。

所以(最终)回答你的问题,如果你没有配置一个映射器(并且正在使用默认值或识别映射器,因为它也是已知的),那么是的,XML块有多大(MB,GB , TB 的!)它将被发送到减速器。

我希望这是有道理的。

编辑

要跟进您的评论:

  1. 是的,每个映射器都将尝试处理文件的拆分(字节范围)
  2. 是的,无论您设置的最大拆分大小如何,您的映射器都将接收代表开始/结束标签之间(包括)之间数据的记录。person 元素无论其大小如何都不会被拆分(显然,如果在 start 和 end 元素之间存在 GB 的数据,您很可能会在尝试将其缓冲到 Text 对象中时耗尽内存)
  3. Continuing from the above, your data will never be split up between the start and end element, a person element will be sent in its entirity to a mapper, so you should always be ok using something like a SAX parser to further process it without fear that you're only seeing a portion of the person element.
于 2012-10-02T01:20:12.970 回答