36

我们有一个大型数据集可以使用多个reduce函数进行分析。

所有reduce算法都在同一个map函数生成的同一个数据集上工作。每次读取大数据集的成本太高,最好只读取一次并将映射的数据传递给多个reduce函数。

我可以用 Hadoop 做到这一点吗?我搜索了示例和 intarweb,但找不到任何解决方案。

4

6 回答 6

11

也许一个简单的解决方案是编写一个没有 reduce 函数的作业。因此,您可以将所有映射数据直接传递到作业的输出。您只需将作业的减速器数量设置为零。

然后,您将为处理该数据的每个不同的 reduce 函数编写一个作业。这意味着将所有映射数据存储在 HDFS 上。

另一种选择可能是将所有 reduce 函数组合到一个 Reducer 中,该 Reducer 输出到多个文件,为每个不同的函数使用不同的输出。本文提到了 hadoop 0.19 的多个输出。我很确定这个特性在 0.20.1 发布的新 mapreduce API 中被破坏了,但是你仍然可以在旧的 mapred API 中使用它。

于 2010-02-26T22:33:04.707 回答
4

您是否希望每个 reducer 都能处理完全相同的映射数据?但至少“关键”应该不同,因为它决定了使用哪个减速器。

您可以在 mapper 中多次编写输出,并将输出作为键(其中 $i 用于第 i 个 reducer,$key 是您的原始键)。并且您需要添加一个“分区器”以确保这 n 条记录基于 $i 分布在减速器中。然后使用“GroupingComparator”按原始 $key 对记录进行分组。

有可能做到这一点,但不是在一个 MR 中以微不足道的方式。

于 2010-02-26T05:07:50.720 回答
3

您可以使用复合键。假设您需要两种减速器,“R1”和“R2”。为这些添加 id 作为映射器中的 o/p 键的前缀。因此,在映射器中,键“K”现在变为“R1:K”或“R2:K”。

然后,在 reducer 中,根据前缀将值传递给 R1 或 R2 的实现。

于 2011-03-30T18:06:58.083 回答
1

我猜你想在一个链中运行不同的减速器。在 hadoop 中,“多个减速器”意味着运行同一个减速器的多个实例。我建议您一次运行一个减速器,为除第一个之外的所有减速器提供微不足道的地图功能。为了尽量减少数据传输的时间,您可以使用压缩。

于 2011-04-27T10:17:45.750 回答
0

当然你可以定义多个reducer。对于作业(Hadoop 0.20),只需添加:

job.setNumReduceTasks(<number>);

但。您的基础架构必须支持多个减速器,这意味着您必须

  1. 有多个可用的 CPU
  2. 相应地调整 mapred-site.xml 中的 mapred.tasktracker.reduce.tasks.maximum

当然,您的工作必须符合某些规范。在不知道您到底想做什么的情况下,我只能提供广泛的提示:

  • 映射输出必须可以通过 %numreducers 进行分区,或者您必须定义自己的分区器: job.setPartitionerClass(...) 例如使用随机分区器 ...
  • 数据必须是可归约的分区格式...(需要参考?)

您将获得多个输出文件,每个减速器一个。如果你想要一个排序的输出,你必须添加另一个读取所有文件的作业(这次是多个映射任务......)并只用一个减速器将它们排序......

也可以看看Combiner-Class,它是本地的Reducer。这意味着您可以对 map 发出的部分数据在内存中进行聚合(减少)。非常好的例子是 WordCount-Example。Map 将每个单词作为键发出,其计数为 1:(word, 1)。组合器从地图中获取部分数据,在本地发出 (, )。Reducer 的作用完全相同,但现在一些(组合)字数已经 >1。节省带宽。

于 2010-02-26T00:00:57.210 回答
0

我仍然没有得到您的问题,您可以使用以下顺序:

database-->map-->reduce(根据需要使用 cat 或 None)然后存储您提取的数据表示。如果您说它足够小以适合内存,那么将其存储在磁盘上应该不是问题。

此外,您对给定问题使用 MapReduce 范式是不正确的,使用单个 map 函数和多个“不同”reduce 函数没有意义,这表明您只是使用 map 将数据传递给不同的机器来做不同的事情。您不需要 hadoop 或任何其他特殊架构。

于 2010-02-28T06:10:31.130 回答