4

这就是我想要做的。现在我有一些像这样的文本文件:

<page>
<url>xxx.example.com</url>
<title>xxx</title>
<content>abcdef</content>
</page>

<page>
<url>yyy.example.com</url>
<title>yyy</title>
<content>abcdef</content>
</page>

...

我想读取映射器中拆分的文件并将它们转换为键值对,其中每个值都是一个<page> 标记中的内容。

我的问题是关于钥匙。我可以使用 url 作为键,因为它们是全局唯一的。但是,由于我的工作背景,我想为每个键值对生成一个全局唯一编号作为键。我知道这在某种程度上违背了 Hadoop 的水平可扩展性。但是有什么解决办法吗?

4

2 回答 2

2

如果您要通过 MapReduce 处理此类文件,我将采取以下策略:

  1. 逐行使用一般文本输入格式。这导致每个不同的文件都转到不同的映射器作业。
  2. 在映射器构建周期中,它在循环中读取下一行,context.nextKeyValue()而不是为每一行调用。
  3. 向某些语法分析器提供行(也许你只够阅读 6 条非空行,也许你会使用libxml之类的东西,但最后你会生成对象的数量。
  4. 如果您打算将读取的对象传递给减速器,则需要将它们包装成实现接口的东西Writable
  5. 要形成密钥,我会使用 UUID implementation java.util.UUID。就像是:

    UUID 键 = UUID.randomUUID();

    如果您没有每秒生成数十亿条记录并且您的工作不需要 100 年,这就足够了。:-)

  6. 请注意 - UUID 可能应该在ImmutableBytesWritable类中编码,对此类事情很有用。

  7. 就是这样,context.write(object,key)

好的,你的减速器(如果有的话)和输出格式是另一回事。如果您不在Text映射期间将它们转换为类似的东西,您肯定需要输出格式来存储您的对象。

于 2013-05-28T05:06:53.047 回答
0

不确定这是否直接回答了您的问题。但我正在利用输入文件格式。

您可以使用NLineInputFormat并设置 N = 6,因为每条记录包含 6 行:

<page>
<url>xxx.example.com</url>
<title>xxx</title>
<content>abcdef</content>
</page>
.

对于每条记录,映射器将获取文件中的偏移位置。这个偏移量对于每条记录都是唯一的。

PS:只有在架构固定时才会起作用。我怀疑它是否适用于多个输入文本文件。

于 2013-05-26T11:18:27.730 回答