所以要清除一些东西:
Mahout的XMLInputFormat将处理XML文件,并在两个已配置的开始/结束标记之间提取XML。因此,如果您的XML如下所示:
<main> <person> <name>Bob</name> <dob>1970/01/01</dob> </person></main>
并且您已将开始/结束标记配置为
<person>和
</person>,那么您的映射器将通过以下
<LongWritable,Text>对传递到其map方法:
LongWritable: 10Text: "<person>n <name>Bob</name>n <dob>1970/01/01</dob>n </person>"
然后,您就可以在映射器中处理此数据。
关于splits,
XmlInputFormatextends
TextInputFormat,因此,如果您输入的文件是可拆分的(即未压缩或使用可拆分的编解码器(例如snappy)压缩),则该文件将由一个或多个映射器处理,如下所示:
- 如果输入文件的大小(比如说48 MB)小于HDFS中的单个块(比如说64MB),并且您没有配置最小/最大拆分大小属性,那么您将获得一个映射器来处理文件
- 和上面一样,但是您将最大拆分大小配置为10MB(
mapred.max.split.size=10485760
),那么您将获得5个映射任务来处理文件 - 如果文件大于块大小,那么您将获得每个块的映射任务,或者如果配置了最大拆分大小,则将文件划分为该拆分大小的每个部分的映射
当文件拆分为这些块或拆分大小的块时,XmlInputFormat将寻求对块的字节地址/偏移量/拆分边界进行查找,然后向前扫描,直到找到配置的XML起始标记或到达块的字节地址为止/分割边界。如果找到开始标签,它将消耗数据直到找到结束标签(或文件末尾)。如果找到结束标记,则记录将被传递到您的映射器,否则您的映射器将不会收到任何输入。要强调的是,在尝试找到结束标签时,地图可能会扫描到块/拆分的末尾,但只有找到开始标签后才会执行此操作,否则扫描将在块/拆分的末尾停止。
因此,要(最终)回答您的问题,如果您尚未配置映射器(并且正在使用默认值或标识映射器,因为它是众所周知的),那么是的,XML块的大小(MB,GB)无关紧要,TB!)它将被发送到减速器。
我希望这是有道理的。
编辑
跟进您的评论:
- 是的,每个映射器都会尝试处理文件的拆分(字节范围)
- 是的,无论您也设置了最大拆分大小是多少,映射器都会收到记录,这些记录代表开始/结束标记之间(包括两端)的数据。无论person元素的大小如何,都不会拆分它(显然,如果start和end元素之间存在GB的数据,则很可能会用尽内存来尝试将其缓冲到Text对象中)
- 从上面继续,您的数据将永远不会在开始元素和结束元素之间分割,人员元素将以其完整性发送到映射器,因此您应该始终可以使用SAX解析器之类的东西来进一步处理它而不必担心您只会看到person元素的一部分。



