Hadoop一个Map和多个Reduce

时间:2010-02-25 11:34:18

标签: hadoop mapreduce

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

所有 reduce 算法都适用于由相同地图函数生成的同一数据集。读取大型数据集每次都要花费太多,最好只读一次并将映射数据传递给多个 reduce 函数。

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

6 个答案:

答案 0 :(得分:11)

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

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

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

答案 1 :(得分:4)

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

您可以在mapper中多次编写输出,并输出为键(其中$ i表示第i个reducer,$ key表示原始键)。并且您需要添加“分区程序”以确保这些n条记录基于$ i分配在reducer中。然后使用“GroupingComparator”按原始$ key对记录进行分组。

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

我想你想在链中运行不同的reducer。在hadoop中,“多个减速器”意味着运行同一减速器的多个实例。我建议你一次运行一个减速器,为除了第一个之外的所有减速器提供简单的地图功能。为了最大限度地缩短数据传输时间,您可以使用压缩。

答案 4 :(得分:0)

当然,您可以定义多个减速器。对于Job(Hadoop 0.20),只需添加:

job.setNumReduceTasks(<number>);

但是。您的基础架构必须支持多个Reducer,这意味着您必须

  1. 有多个cpu可用
  2. 相应调整mapred-site.xml中的mapred.tasktracker.reduce.tasks.maximum
  3. 当然,你的工作必须符合一些规范。在不知道你想要做什么的情况下,我只能给出一些提示:

    • map-output 要么可以被%numreducers分区,要么你必须定义自己的分区器: job.setPartitionerClass(...) 例如,使用随机分区器......
    • 数据必须以分区格式减少...(需要引用?)

    您将获得多个输出文件,每个缩减器一个。如果你想要一个排序的输出,你必须添加另一个读取所有文件的作业(这次是多个map-tasks ...)并且只用一个reducer编写它们...

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

答案 5 :(得分:0)

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

数据库 - &gt;地图 - &gt;减少(根据要求使用cat或None) 然后存储您提取的数据表示。 如果你说它足够小以适应内存,那么将它存储在磁盘上应该是一个问题。

另外你对给定问题使用MapReduce范例是不正确的,使用单个map函数和多个“不同”reduce函数毫无意义,它表明你只是使用map将数据传递给不同的机器来做不同的事情的东西。你不需要hadoop或任何其他特殊的架构。