我是Hadoop MapReduce的新手(确切地说是4天),我被要求在集群上执行分布式XML解析.根据我在互联网上的(重新)搜索,使用Mahout的XmlInputFormat应该相当容易,但我的任务是确保系统适用于大型(~5TB)XML文件.
据我所知,发送给映射器的文件拆分不能大于hdfs块大小(或每个作业块大小).[纠正我,如果我弄错了].
我面临的问题是一些XML元素很大(~200MB),有些很小(~1MB)
所以我的问题是:当XmlInputFormat创建的XML元素块大于块大小时会发生什么?它会将整个大文件(比方说200MB)发送给映射器还是将它发送出三个分区(64 + 64 + 64 + 8)?
我目前无法访问公司的hadoop集群(并且不会在某个时间之前),所以我无法执行测试并找出答案.请帮助我.
所以要清楚一些事情:
Mahout的XMLInputFormat将处理XML文件并在两个配置的开始/结束标记之间提取XML.因此,如果您的XML如下所示:
Bob 1970/01/01
你已经配置好了开始/结束标记是
和,那么你的映射器将传递以下
对到其地图的方法:
LongWritable: 10 Text: "\n "Bob \n1970/01/01 \n
您在映射器中对此数据执行的操作由您决定.
关于分割,XmlInputFormat
扩展TextInputFormat
,所以如果您输入文件是可拆分的(即未压缩或使用可拆分编解码器(如snappy)压缩),则文件将由一个或多个映射器处理,如下所示:
如果输入文件大小(比如说48 MB)小于HDFS中的单个块(比方说64 MB),并且您没有配置最小/最大拆分大小属性,那么您将获得一个映射器来处理该文件
与上面一样,但是您将最大拆分大小配置为10MB(mapred.max.split.size=10485760
),那么您将获得5个映射任务来处理该文件
如果文件大于块大小,那么您将获得每个块的映射任务,或者如果配置了最大分割大小,则按分割大小划分文件的每个部分的映射
当文件被拆分为这些块或拆分大小的块时,XmlInputFormat将寻找块/拆分边界的字节地址/偏移量,然后向前扫描,直到找到已配置的XML开始标记或到达块的字节地址为止/分裂边界.如果它找到了开始标记,它将使用数据,直到找到结束标记(或文件结尾).如果找到结束标记,则记录将传递给您的映射器,否则您的映射器将不会收到任何输入.要强调的是,在尝试查找结束标记时,地图可能会扫描块/拆分的末尾,但只有在找到开始标记时才会扫描,否则扫描会在块/拆分结束时停止.
所以(最终)回答你的问题,如果你还没有配置映射器(并且正在使用默认或识别映射器,因为它也是已知的),那么是的,XML块的大小并不重要(MB,GB的,TB的!)它将被发送到减速机.
我希望这是有道理的.
编辑
跟进你的意见:
是的,每个映射器将尝试处理其文件的分割(字节范围)
是的,无论您设置的最大分割大小如何,您的映射器都将接收表示开始/结束标记(包括)之间数据的记录.person元素不会被拆分而不管它的大小是什么(显然如果在开始和结束元素之间有GB的数据,你很可能会耗尽内存试图将它缓冲到Text对象中)
继续上面的描述,你的数据永远不会在开始和结束元素之间分开,一个person元素将以其整体的形式发送给mapper,所以你应该总是可以使用类似SAX解析器的东西来进一步处理它而不用担心你只看到了person元素的一部分.