我正在尝试编写一个mapreduce程序来计算一些统计数据的平均值。
映射器读取其各自段中的数据并执行一些过滤器。
我正在使用多个Reducers。
因此,reducer将只能计算该分区中的局部平均值。然而,我需要所有减速器的所有数据的平均值。我该怎么做呢?
一个想法是使用全局计数器来保存总和和计数。但我需要一段代码,在所有减速器运行后运行(这样我可以对最终总和和计数进行操作)并将平均值输出到文件中。这是一种可行的方法,我该怎么做?
另请注意,我必须使用多个reducer。因此,只有一个reducer并在清理方法中进行平均计算的选项是不可能的。
答案 0 :(得分:0)
选项1 .-实施合并器并仅使用一个reducer。组合器将减少要传输到减速器的数据量。如果使用多个reducer的原因是您正在处理的数据量,这可能是一个选项。
选项2 .-每个Mapper内部计算内存中的部分和/计数,只需将清除方法中的聚合值写入输出。允许您仅使用一个减速器来计算最终平均值。
选项3 .-使用两个map-reduce作业实施您的流程。一个用于计算每个reducer中的部分和/ count,然后用身份映射计算其他map-reduce,只用一个reducer来计算平均值。
选项4 .-使用计数器,正如@Thomas建议的那样,在waitForCompletion之后实现逻辑。
选项5 .-使用reducer的输出来计算HDFS文件的平均读数(使用计数器可能更简单)。
在我看来,选项2是最简单和最干净的实现。选项1是最通用的选项,如果您需要同时计算多个平均值并计算内存中的总数/计数,则非常有用(计数器限制性更强,只有几千个)。
答案 1 :(得分:0)
如果你坚持使用多个Reducer来完成这项工作,那么我猜你应该做多个(在你的情况下是2)工作链。第一份工作将做你现在所做的一切。第二项工作将设置为计算总体平均值。所以第一份工作的输出作为第二份工作的输入。
您可以看到我的答案here,了解如何在单个驱动程序类中设置一系列作业。