【问题标题】:Running Code after all reducers run在所有 reducer 运行后运行代码
【发布时间】:2016-07-04 20:29:30
【问题描述】:

我正在尝试编写一个计算某些统计数据平均值的 mapreduce 程序。

映射器读取其各自段中的数据并执行一些过滤器。

我正在使用多个 Reducer。

因此,reducer 将能够仅计算该分区中的局部平均值。但是,我需要所有减速器的所有数据的平均值。我该如何解决这个问题?

一个想法是使用全局计数器来保存总和和计数。但是我需要在所有减速器运行后运行的一段代码(以便我可以对最终的总和和计数进行操作)并将平均值输出到文件中。这是一种可行的方法吗?我该怎么做?

还要注意我必须使用多个减速器。因此,仅使用一个 reducer 并在 cleanup 方法中进行平均计算的选项是不可能的。

【问题讨论】:

  • waitForCompletion()之后的驱动代码中做

标签: java hadoop mapreduce


【解决方案1】:

选项 1.- 实现 combiner 并仅使用一个 reducer。组合器将减少要传输到化简器的数据量。如果使用多个 reducer 的原因是您正在处理的数据量,这可能是一种选择。

选项 2.- 在每个 Mapper 中计算内存中的部分总和/计数,然后将清理方法中的聚合值写入输出。允许您仅使用一个 reducer 来计算最终平均值。

选项 3.- 使用两个 map-reduce 作业实现您的流程。一个用于计算每个 reducer 中的部分总和/计数,然后是另一个带有恒等映射的 map-reduce,并且只有一个 reducer 来计算平均值。

选项 4.- 使用计数器,并按照@Thomas 的建议,在 waitForCompletion 之后实现逻辑。

选项 5.- 使用减速器的输出来计算读取 HDFS 文件的平均值(使用计数器可能更简单)。

在我看来,选项 2 是最简单、最干净的实现方式。选项 1 是最通用的选项,如果您需要同时计算多个平均值并且无法计算内存中的总和/计数,则非常有用(计数器限制性更强,只有数千个)。

【讨论】:

    【解决方案2】:

    如果您坚持使用多个减速器来完成这项工作,那么我想您应该执行多个(在您的情况下为 2)工作链。第一份工作将完成你现在拥有的一切。第二个作业将设置为计算总体平均值。所以第一个作业的输出作为第二个作业的输入。

    您可以查看我的回答 here,了解如何在单个驱动程序类中设置作业链。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2016-07-31
      相关资源
      最近更新 更多