Hadoop 一个 Map 和多个 Reduce
Posted
技术标签:
【中文标题】Hadoop 一个 Map 和多个 Reduce【英文标题】:Hadoop one Map and multiple Reduce 【发布时间】:2011-01-20 23:24:20 【问题描述】:我们有一个大型数据集要使用多个 reduce 函数进行分析。
所有 reduce 算法都适用于由相同 map 函数生成的相同数据集。每次读取大型数据集成本太高,最好只读取一次并将映射数据传递给多个reduce函数。
我可以用 Hadoop 做到这一点吗?我搜索了示例和 intarweb,但找不到任何解决方案。
【问题讨论】:
【参考方案1】:也许一个简单的解决方案是编写一个没有 reduce 函数的作业。因此,您可以将所有映射数据直接传递到作业的输出。您只需将作业的减速器数量设置为零即可。
然后,您将为处理该数据的每个不同 reduce 函数编写一个作业。这意味着将所有映射数据存储在 HDFS 上。
另一种选择可能是将所有 reduce 函数组合到一个 Reducer 中,该 Reducer 输出到多个文件,为每个不同的函数使用不同的输出。 this article for hadoop 0.19 中提到了多个输出。我很确定这个功能在 0.20.1 发布的新 mapreduce API 中被破坏了,但你仍然可以在旧的 mapred API 中使用它。
【讨论】:
【参考方案2】:您是否希望每个 reducer 都处理完全相同的映射数据?但至少“关键”应该不同,因为它决定了使用哪个减速器。
您可以在 mapper 中多次编写输出,并作为键输出(其中 $i 用于第 i 个 reducer,$key 是您的原始键)。并且您需要添加一个“分区器”以确保这 n 条记录基于 $i 分布在减速器中。然后使用“GroupingComparator”按原始 $key 对记录进行分组。
这是可能的,但不是在一个 MR 中以微不足道的方式。
【讨论】:
但是如果我使用context.write()
方法向输出添加一个新键,它将从Mapper
对象传输多个数据。它只解决了文件读取问题,不是吗?
那么我建议将映射的数据输出为文件,并使用另一个 MR 来处理这些文件。【参考方案3】:
您可以使用复合键。假设您需要两种减速器,“R1”和“R2”。将这些的 id 作为前缀添加到映射器中的 o/p 键。因此,在映射器中,键“K”现在变为“R1:K”或“R2:K”。
然后,在 reducer 中,根据前缀将值传递给 R1 或 R2 的实现。
【讨论】:
【参考方案4】:我猜你想在一个链中运行不同的减速器。在 hadoop 中,“多个减速器”意味着运行同一个减速器的多个实例。我建议您一次运行一个减速器,为除第一个之外的所有减速器提供微不足道的地图功能。为了最大限度地减少数据传输的时间,您可以使用压缩。
【讨论】:
【参考方案5】:当然你可以定义多个reducer。对于 Job (Hadoop 0.20),只需添加:
job.setNumReduceTasks(<number>);
但是。您的基础架构必须支持多个减速器,这意味着您必须
-
有多个可用的 CPU
相应地调整 mapred-site.xml 中的 mapred.tasktracker.reduce.tasks.maximum
当然,您的工作必须符合某些规范。在不知道您到底想做什么的情况下,我只能提供广泛的提示:
keymap-output 要么可以被 %numreducers 分区,要么你必须定义你自己的分区器:job.setPartitionerClass(...)
例如使用随机分区器...
数据必须是可归约的分区格式...(需要引用?)
您将获得多个输出文件,每个减速器一个。如果你想要一个排序的输出,你必须添加另一个读取所有文件的作业(这次是多个 map-tasks ......)并只用一个 reducer 将它们排序......
看看Combiner-Class,它是local Reducer。这意味着您可以对 map 发出的部分数据在内存中进行聚合(减少)。 非常好的例子是 WordCount-Example。 Map 将每个单词作为键发出,其计数为 1:(word, 1)。组合器从地图中获取部分数据,在本地发出 (, )。 Reducer 的作用完全相同,但现在一些(组合)字数已经 >1。节省带宽。
【讨论】:
据我所知; OP 询问“具有多个减速器实现”,而您正在谈论“相同减速器代码的多个实例”。这是完全不同的东西。【参考方案6】:我还是不明白你的问题,你可以使用以下顺序:
database-->map-->reduce(根据需要使用 cat 或 None) 然后存储您提取的数据表示。 如果您说它足够小以适合内存,那么将其存储在磁盘上应该不是问题。
另外你对给定问题使用 MapReduce 范式是不正确的,使用单个 map 函数和多个“不同”reduce 函数没有意义,这表明你只是使用 map 将数据传递到不同的机器来做不同的事情事物。您不需要 hadoop 或任何其他特殊架构。
【讨论】:
map reduce 是一种通过利用多台机器更快地完成单个进程的范例,但使用相同的数据做不同的事情并不是 map reduce。单张地图和多张减少也没有任何意义。最多你可以做的是使用 map1->reduce1->map2(do the work)->reduce2 map2 应该对数据的多个拆分执行单个函数。以上是关于Hadoop 一个 Map 和多个 Reduce的主要内容,如果未能解决你的问题,请参考以下文章