2009-09-30 90 views
2

我在考虑在hadoop中构建一个小测试应用程序以获取系统的挂起。在将值发送给reducer之前对值进行排序

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

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

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

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


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

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

回答

1

听起来好像你想要使用一个组合器,它定义了如何处理在Map端创建的值,然后再将它们发送到Reducer,但是在按键分组后。 组合器通常被设置为reducer类(所以你减少了地图侧,然后再减少)。

看一看的例子的wordCount如何使用组合预先计算部分计数:

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


更新 这就是我心目中的您的问题;不过,我可能误解了你正在尝试做的事情。

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

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

的减速将得到<key, [set of top-10-sets]> - 所有它做的是执行排序合并的合并步骤(不排序需要)为每个数值组成员,并停止在合并时,前10个值被上拉。


更新2

所以,现在我们知道了等级作为cumilative,因此,你不能将数据早期采用组合过滤,唯一的事情是做什么的你建议 - 进行二次排序。你找到了合适的门票;有一个如何在src/examples/org/apache/hadoop/examples/SecondarySort中的Hadoop 20中执行此操作的示例。java(或者,如果你不想下载整个源代码树,你可以看看https://issues.apache.org/jira/browse/HADOOP-4545中的示例补丁)

+0

嗯,据我了解合并的目的是为“这是一个特定节点上运行的部分减速”。在那个时候我不能截断结果,因为我不知道当时的价值的总体“质量”。 – 2009-10-01 10:13:03

+0

更新:有趣的建议。这样做(组合已经截断的子集)通常会导致与“确切”的做法不同的输出。这对我的情况可能会足够好。我会考虑的。谢谢。 – 2009-10-01 20:05:54

+0

你能解释为什么这会导致不同的输出?我认为,全球排名前10位的项目肯定包含在每个分区的前10项(可能是前3名,后2名,前5名 - 但他们都在那里)。 – SquareCog 2009-10-01 21:02:55

4

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

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

使用此方法,您可以控制,但是最好/最差/最高/最低的按键首先会到达减速器。所以读完这10个键之后,可以不做任何进一步的迭代就离开reduce方法。

希望那是有帮助:-)