Hadoop:我如何在Mapper中为每个值提供全局唯一ID号作为键?

时间:2013-05-26 09:39:00

标签: java hadoop mapreduce

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

<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>

...

我想读取mapper中的文件并将它们转换为键值对,其中每个值都是一个<page&gt;中的内容。标签

我的问题是关键。我可以使用网址作为密钥,因为它们是全球唯一的。但是,由于我的工作环境,我想生成一个全局唯一编号作为每个键值对的键。我知道这在某种程度上违背了Hadoop的横向可扩展性。但这有什么解决方案吗?

2 个答案:

答案 0 :(得分:2)

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

  1. 逐行使用常规文本输入格式。这导致每个不同的文件转到不同的映射器作业。
  2. 在mapper构建周期中,通过context.nextKeyValue()循环读取下一行,而不是为每一行调用。
  3. 输入一些语法分析器的行(也许你只需阅读6个非空行,也许你会使用像libxml这样的东西,但最后你会得到一些对象。
  4. 如果您打算将读取的对象传递给reducer,则需要将它们包装成实现Writable交互面的内容。
  5. 要形成密钥,我将使用UUID实现java.util.UUID。类似的东西:

    UUID key = UUID.randomUUID();

    如果你不是每秒产生数十亿条记录就足够了,你的工作不需要100年。 : - )

  6. 请注意 - UUID可能应该在ImmutableBytesWritable类中编码,对此类内容非常有用。

  7. 这就是全部,context.write(object,key)
  8. 好的,你的reducer(如果有的话)和输出格式是另一个故事。如果在映射期间没有将它们转换为Text之类的内容,那么您肯定需要输出格式来存储对象。

答案 1 :(得分:0)

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

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

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

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

PS:仅在架构修复后才有效。我怀疑它是否适用于多个输入文本文件。