在将值发送到reducer之前对值进行排序

时间:2009-09-30 15:29:51

标签: sorting hadoop mapreduce

我正在考虑在hadoop中构建一个小型测试应用程序以获得系统的支持。

我想到的应用程序将处于统计数据领域。 我希望从我的reducer函数中得到“每个键的10个最差值”(我必须假设某些键的值可能很大)。

我的计划是进入我的减速器的值基本上是“实际值”和“实际值的质量/相关性”的组合。 基于相关性,我“简单地”想要获取10个最差/最佳值并从减速器输出它们。

我该如何做(假设特定键的值很大)? 有没有一种方法可以在将所有值发送到reducer之前对其进行排序(当我读取前10个时只是停止读取输入)或者必须以不同的方式完成这些操作?

有人可以在这里指出我可以查看的一段示例代码吗?


更新:我发现了两个有趣的Jira问题HADOOP-485HADOOP-686

任何人都有关于如何在Hadoop 0.20 API中使用它的代码片段吗?

3 个答案:

答案 0 :(得分:4)

听起来像SecondarySortProblem。如果您愿意,请查看“Hadoop:权威指南”。它来自O'Reilly。您也可以在线访问它。在那里,他们描述了一个非常好的实现。

我也是自己实施的。基本上它以这种方式工作: 分区程序将关注所有键值对,使用相同的键转到单个reducer。这里没什么特别的。 但也有GroupingComparator,它将形成分组。实际上,一个组作为迭代器传递给一个reduce() - 调用。因此,分区可以包含多个分组。但是分区的数量应该等于减少器的数量。但是分组还允许在实现compareTo方法时进行一些排序。

使用此方法,您可以控制10个最佳/最差/最高/最低键然后首先到达减速器。因此,在阅读了这10个键之后,您可以不使用任何进一步的迭代来保留reduce方法。

希望这有用: - )

答案 1 :(得分:1)

听起来你想使用一个Combiner,它定义了你在发送到Reducer之前在Map端创建的值如何处理,但是在按键分组之后。 组合器通常设置为减速器类(因此您在地图侧减少,然后在减少侧再次减少)。

看一下wordCount示例如何使用组合器预先计算部分计数:

http://wiki.apache.org/hadoop/WordCount


更新 这就是我对你的问题的想法;但是,我可能误解了你想要做的事情。

每个映射器都会发出<key, {score, data}>对。

组合器获取这些对的部分集合:<key, [set of {score, data}>并进行局部排序(仍在映射器节点上),并输出<key, [sorted set of top 10 local {score, data}]>对。

reducer将获得<key, [set of top-10-sets]> - 它所要做的就是为值集的每个成员执行sort-merge的合并步骤(不需要排序),并在前10个时停止合并价值被拉动。


更新2

所以,既然我们知道排名是累积性的,那么你就不能通过使用组合器来尽早过滤数据,唯一的办法就是按照你的建议去做 - 进行二次排序。你找到了合适的门票;在src / examples / org / apache / hadoop / examples / SecondarySort.java中有一个如何在Hadoop 20中执行此操作的示例(或者,如果您不想下载整个源代码树,可以查看示例补丁https://issues.apache.org/jira/browse/HADOOP-4545

答案 2 :(得分:0)

如果我理解正确,您需要使用TotalOrderPartitioner