Hadoop:how XML 文件可以存储在HDFS中并由Mappers处理吗?

Hadoop:how XML files can be stored in HDFS and processed by Mappers?

我刚刚开始学习 Hadoop,我想确认一下我对 'how XML files can be stored in HDFS and processed by 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>
...
...

现在,如果我理解正确的话,考虑每个完整的 <customer></customer> 标记进行处理的 MappReduce 作业的 Mapper 可能会失败,因为使用 -put 将这种 XML 文件放入 HDFS或 -copyFromLocal 不保证 HDFS 中的每个拆分块都将包含 n 个完整的 <customer></customer> 标记。一些拆分块可能会像下面这样结束。

   ...
   ...

       <customer>
        <id></id>
        <name></name>
        <age></age>
        <address></address>
       </customer>
       <customer>
        <id></id>
        <name></name>

现在如果我们要确保每个块都必须有一个完整的客户标签'<customer></customer>',我们可以采用以下解决方案。

  1. Avro : 将每个客户 XML 转换为 Avro 类型,如记录类型,并使用 Avro 序列化并将此文件作为 'Avro data file' 放入 HDFS,支持splittablity,可以保证一个block中有一条完整的Avro记录。
  2. 序列文件:我不确定这个,但我认为我们可以在创建序列文件时标记同步点,这些文件在将文件拆分为块时使用。这里我们可以将每个客户标签 '</customer>' 的结尾标记为同步点,这将保证在同一块中没有客户开始标签 '<customer>' 会在没有结束标签的情况下结束。

谁能证实我的理解是否正确?请问除了这两个还有其他方法可以解决吗

记录不必是映射器的本地记录,只是出于性能原因更可取。大多数 MapReduce 输入格式将寻找超过块的末尾以完成块的最终记录。这会在流程中引入一些远程读取,但占总读取的比例通常非常低。

Mahout XmlInputFormat 正是这样做的。每次运行 next() 以创建新记录时,它都会从最后一个完成点开始扫描,并且只有在确定下一条记录完全跨越分配给映射器的拆分之外时才会拒绝 return 下一条记录。

您的理解是正确的,预计映射器 运行 从块派生的拆分而不是完整的块。所以映射器肯定会更多。

所以来到XML文件的存储,他们会按照序列化的概念进入HDFS,在读取的时候进行反序列化(SerDes) 除了 AVRO 之外,还引入了其他 SerDes。比如节俭等等