【问题标题】:hadoop MapReduce: find max key value pair from output of mapperhadoop MapReduce:从映射器的输出中查找最大键值对
【发布时间】:2011-12-13 06:18:23
【问题描述】:

这听起来像是一项简单的工作,但使用 MapReduce 似乎并不那么简单。

我有 N 个文件,其中每个文件只有一行文本。我希望 Mapper 输出键值对,例如 ,其中“分数”是从文本行计算的整数。作为旁注,我使用下面的 sn-p 这样做(希望它是正确的)。

 FileSplit fileSplit = (FileSplit)reporter.getInputSplit();
 String fileName = fileSplit.getPath().getName();

假设映射器正确地完成了它的工作,它应该输出 N 个键值对。 现在的问题是我应该如何对 Reducer 进行编程以输出具有最大 'score' 的一个键值对

据我所知,Reducer 仅适用于共享相同键的键值对。由于这种情况下的输出都有不同的键,我猜应该在 Reduce 步骤之前做一些事情。或者也许应该完全省略 Reduce 步骤?

【问题讨论】:

    标签: java hadoop mapreduce


    【解决方案1】:

    假设

    File1 有 10,123,23,233

    File2 有 1,3,56,1234

    File3 有 6,1,3435,678


    这是从所有输入文件中找到最大数量的方法。

    1. 让我们先做一些随机抽样(比如每 N 条记录)。来自 File1 123 和 10,来自 File2 56 和 1,来自 File3 1 和 678。

    2. 从随机抽样中选择最大的数,即 678。

    3. 将随机采样的最大数字传递给映射器,忽略输入数字减去随机采样中找到的最大数字,并在映射器中发出其他数字。映射器将忽略小于 678 的任何内容并发出 678、1234 和 3435。

    4. 将作业配置为使用 1 个减速器并找到发送到减速器的所有数字的最大值。在这种情况下,reducer 将收到 678、1234 和 3435。并将计算出最大数量为 3435。


    对上述方法的一些观察

    1. 数据必须传递两次。

    2. mapper 和 reducer 之间传输的数据减少了。

    3. reducer 处理的数据也减少了。

    4. 更好的输入采样,更快的作业完成。

    5. 具有与 Reducer 类似功能的 Combiner 将进一步缩短作业时间。

    【讨论】:

    • 这不是我的问题,但仍然感谢您的洞察力。
    • 有什么区别?我以为你想从所有输入文件中找出最高分。
    【解决方案2】:

    您可以使用 setup() 和 cleanup() 方法(旧 API 中的 configure() 和 close() 方法)。 在reduce类中声明一个全局变量,它决定了最高分。对于每个 reduce 调用,您将输入值(分数)与全局变量进行比较。

    Setup() 在同一个reduce 任务中的所有reduce 调用之前调用一次。 Cleanup() 在同一个reduce 任务中最后一次reduce 调用之后被调用。因此,如果您有多个 reducer,Setup() 和 cleanup() 方法将在每个 reduce 任务上分别调用。

    【讨论】:

    • 方法不完整。如果有多个 reducer,那么每个 reducer 都会发出特定文件中的最大值作为输出。同样,这必须进行排序并找出最大值。或者将reducer的数量设置为1。
    • 我有一个问题:不应该还有N个输出(因为每个Reducer都应该写出自己的结果)?而且即使Reducer的个数是1,我认为Reducer也不会愿意拿走所有的键值对。
    • 如果你只配置一个reducer,这个效果很好。无需投票。
    • @yongtw123 如果只配置 1 个 reducer,hashpartitioner 可以将每个键/值对分配给这个 reducer。所以每个 k/v 对都将在那里可用。但 Praveen 是对的,它的可扩展性有限。但是对于两个文件就完全没问题了。
    • 由于我需要处理的数据不是很大,这个简单的解决方案对我很有效。谢谢!
    【解决方案3】:

    您可以将文件名和分数作为值返回,并从映射器返回任何常量作为键

    【讨论】:

    • 详细来说,你的建议是创建一个新的 Writable 对象来存储文件名和分数,并在麻烦的 Mapper 和 Reducer 中使用它?
    • 我能够创建我的自定义 Writable 类,但是您能否提供一个示例来说明如何将此自定义 Writable 与 Mapper 和 Reducer 类一起使用?例如我应该在 context.write() 中做什么?我发现的资源对此非常模糊。
    • 您使用 JobConf 的 setMapOutputValueClass。这里有很好的解释developer.yahoo.com/hadoop/tutorial/module5.html
    • 或者使用OP中提到的方法yongtw123将reducer的数量设置为1。但是,问题是只有一个 reducer,这将是一个拥有大量数据的瓶颈。
    • @PraveenSripati 您可以使用组合器完成一些工作(获取每个地图的本地最大值)并在减速器中获取这些最大值
    【解决方案4】:

    请参阅http://www.slideshare.net/josem.alvarez/map-reduceintro 的幻灯片 32 和 33

    我用同样的方法得到了结果。唯一需要注意的是,当您有多个字段时,您需要分别创建 fieldnamemin 和 fieldnamemax。

    【讨论】:

      【解决方案5】:

      省略减速器! 使用 Configuration 将全局变量设置为 score 和 key,然后在 mapper 中访问它,使用全局变量作为 max score 和 key 的内存进行简单的 max score 选择 应该很简单。我猜。

      【讨论】:

      • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
      • 好的...谢谢 :-)(顺便说一句,是否允许使用笑脸?我是论坛的新手。)
      • @DheerajVerma 不鼓励使用表情符号和笑脸。此外,这不是一个论坛,而是一个专注于问答的网站。显而易见的主要方式之一是,每个帖子要么是一个问题,要么是直接答案,要么是与该帖子相关联的要求澄清或澄清的评论。与论坛不同,帖子没有线性的集合,答案可以根据他们的投票或活动重新排序。
      猜你喜欢
      • 2016-01-21
      • 2013-11-06
      • 2021-10-17
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多