我刚刚开始学习Hadoop,我想确认一下我对XML文件如何存储在HDFS中并由Mappers'处理的理解。
我有一个XML格式的XML文件,如下所示。其简单的客户列表XML示例。此文件的大小为1 GB。现在,如果我将此文件移动到HDFS,它将被拆分为16个块(如果我们将每个拆分的默认块大小保持为64 MB)。因此,将执行16个映射器来处理此文件,每个块一个。
<?xml version="1.0"?>
<customerList>
<customer>
<id></id>
<name></name>
<age></age>
<address></address>
</customer>
<customer>
<id></id>
<name></name>
<age></age>
<address></address>
</customer>
...
...
现在,如果我理解正确,MappReduce作业的Mapper考虑每个完整的<customer></customer>
标记进行处理可能会失败,因为使用-put
或-copyFromLocal
将此类XML文件放入HDFS不保证HDFS中的每个拆分块都包含n
个完整<customer></customer>
个标记。一些拆分块可能会如下所示。
...
...
<customer>
<id></id>
<name></name>
<age></age>
<address></address>
</customer>
<customer>
<id></id>
<name></name>
现在,如果我们想确保每个块都必须有完整的客户标记&#39; <customer></customer>
&#39;,我们可以寻求以下解决方案。
</customer>
&#39;作为同步点,这将保证没有客户开始标记&#39; <customer>
&#39;最终会在同一个块中没有结束标记。 任何人都可以确认我的理解是否正确吗?还有其他方法可以解决这两个问题。
答案 0 :(得分:1)
记录不必是映射器的本地记录,出于性能原因,它更为可取。大多数MapReduce输入格式将遍历块的末尾以完成块的最终记录。这引入了一些远程读取过程,但作为总读数的一部分,它通常非常低。
Mahout XmlInputFormat就是这样做的。每次运行next()
以创建新记录时,它会从上一个已完成的点进行扫描,并且只有在确定它完全跨越分配给映射器的拆分之外时才拒绝返回下一条记录。
答案 1 :(得分:0)
您的理解是正确的,期望映射器运行从块而不是完整Block派生的分割。因此,映射器肯定会更多。
为了存储XML文件,他们将遵循序列化的概念,在读取时进入HDFS和反序列化(SerDes) 除了AVRO之外,还有其他SerDes介绍。像节俭等。