我们有一个大型数据集可以使用多个reduce函数进行分析。
所有reduce算法都在同一个map函数生成的同一个数据集上工作。每次读取大数据集的成本太高,最好只读取一次并将映射的数据传递给多个reduce函数。
我可以用 Hadoop 做到这一点吗?我搜索了示例和 intarweb,但找不到任何解决方案。
也许一个简单的解决方案是编写一个没有 reduce 函数的作业。因此,您可以将所有映射数据直接传递到作业的输出。您只需将作业的减速器数量设置为零。
然后,您将为处理该数据的每个不同的 reduce 函数编写一个作业。这意味着将所有映射数据存储在 HDFS 上。
另一种选择可能是将所有 reduce 函数组合到一个 Reducer 中,该 Reducer 输出到多个文件,为每个不同的函数使用不同的输出。本文提到了 hadoop 0.19 的多个输出。我很确定这个特性在 0.20.1 发布的新 mapreduce API 中被破坏了,但是你仍然可以在旧的 mapred API 中使用它。
您是否希望每个 reducer 都能处理完全相同的映射数据?但至少“关键”应该不同,因为它决定了使用哪个减速器。
您可以在 mapper 中多次编写输出,并将输出作为键(其中 $i 用于第 i 个 reducer,$key 是您的原始键)。并且您需要添加一个“分区器”以确保这 n 条记录基于 $i 分布在减速器中。然后使用“GroupingComparator”按原始 $key 对记录进行分组。
有可能做到这一点,但不是在一个 MR 中以微不足道的方式。
您可以使用复合键。假设您需要两种减速器,“R1”和“R2”。为这些添加 id 作为映射器中的 o/p 键的前缀。因此,在映射器中,键“K”现在变为“R1:K”或“R2:K”。
然后,在 reducer 中,根据前缀将值传递给 R1 或 R2 的实现。
我猜你想在一个链中运行不同的减速器。在 hadoop 中,“多个减速器”意味着运行同一个减速器的多个实例。我建议您一次运行一个减速器,为除第一个之外的所有减速器提供微不足道的地图功能。为了尽量减少数据传输的时间,您可以使用压缩。
当然你可以定义多个reducer。对于作业(Hadoop 0.20),只需添加:
job.setNumReduceTasks(<number>);
但。您的基础架构必须支持多个减速器,这意味着您必须
当然,您的工作必须符合某些规范。在不知道您到底想做什么的情况下,我只能提供广泛的提示:
job.setPartitionerClass(...)
例如使用随机分区器 ...您将获得多个输出文件,每个减速器一个。如果你想要一个排序的输出,你必须添加另一个读取所有文件的作业(这次是多个映射任务......)并只用一个减速器将它们排序......
也可以看看Combiner-Class,它是本地的Reducer。这意味着您可以对 map 发出的部分数据在内存中进行聚合(减少)。非常好的例子是 WordCount-Example。Map 将每个单词作为键发出,其计数为 1:(word, 1)。组合器从地图中获取部分数据,在本地发出 (, )。Reducer 的作用完全相同,但现在一些(组合)字数已经 >1。节省带宽。
我仍然没有得到您的问题,您可以使用以下顺序:
database-->map-->reduce(根据需要使用 cat 或 None)然后存储您提取的数据表示。如果您说它足够小以适合内存,那么将其存储在磁盘上应该不是问题。
此外,您对给定问题使用 MapReduce 范式是不正确的,使用单个 map 函数和多个“不同”reduce 函数没有意义,这表明您只是使用 map 将数据传递给不同的机器来做不同的事情。您不需要 hadoop 或任何其他特殊架构。