我们有一个大型数据集可以使用多个 reduce 函数进行分析。
所有 reduce 算法都适用于由相同地图函数生成的同一数据集。读取大型数据集每次都要花费太多,最好只读一次并将映射数据传递给多个 reduce 函数。
我可以用Hadoop做到这一点吗?我搜索过这些例子和intarweb,但我找不到任何解决方案。
答案 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,这意味着您必须
当然,你的工作必须符合一些规范。在不知道你想要做什么的情况下,我只能给出一些提示:
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或任何其他特殊的架构。