6

我有一个由许多小文件(平均每个 30-40 MB)组成的数据集。我想通过 MapReduce 对它们进行分析,但是对于每个作业,映射器都会再次读取文件,这会对 I/O 性能(开销等)造成沉重的负担。

我想知道是否可以使用一次映射器,为不同的减速器发出各种不同的输出?当我环顾四周时,我发现多个减速器是不可能的,但唯一可能的事情是作业链接。但是,我想并行运行这些作业,而不是顺序运行,因为它们都将使用相同的数据集作为输入并运行不同的分析。所以,总而言之,我想要的东西如下:

        Reducer = Analytics1
      /

映射器 - 减速器 = Analytics2

      \
        Reducer = Analytics3 
               ...

这可能吗?或者您对解决方法有什么建议吗?请给我一些想法。重新读取这些小文件会为我的分析带来巨大的开销和性能降低。

提前致谢!

编辑:我忘了提到我正在使用 Hadoop v2.1.0-beta 和 YARN。

4

2 回答 2

3

通过使用自定义分区程序可能是可能的。自定义分区器将根据键将映射器的输出重定向到适当的减速器。因此,映射器输出的键是 R1* 、R2*、R3***。需要研究这种方法的利弊。

如前所述,Tez 是替代方案之一,但仍处于孵化器阶段。

于 2013-10-10T18:23:39.850 回答
3

你可以:

  1. 让你的 reducer 在同一个 pass/job 中完成所有的 Analytics (1-3)。编辑:从您的评论中,我看到这种替代方法对您没有用,但我将其留在这里以供将来参考,因为在某些情况下可以这样做。
  2. 使用比 MapReduce 更通用的模型。例如,Apache Tez(仍然是一个孵化器项目)可用于您的用例。

关于 Apache Tez 的一些有用参考资料:

编辑:添加了关于备选方案 1 的以下内容:

您还可以使映射器生成一个键,指示输出打算用于哪个分析过程。Hadoop 会自动按这个键对记录进行分组,并将它们全部发送到同一个 reducer。映射器生成的值将是表单中的元组<k,v>,其中键 ( k) 是您要生成的原始键。因此,映射器生成<k_analytics, <k,v>>记录。减速器有一个读取键的减速器方法,并根据键调用适当的分析方法(在你的减速器类中)。这种方法可行,但前提是您的 reducer 不必处理大量数据,因为您可能需要在执行分析过程时将其保存在内存中(在列表或哈希表中)(作为<k,v>元组不会按它们的键排序)。如果这不是您的 reducer 可以处理的事情,那么 @praveen-sripati 建议的自定义分区器可能是一个可供探索的选项。

编辑:正如@judge-mental 所建议的,备选方案 1 可以通过映射器问题进一步改进<<k_analytics, k>, value>;换句话说,使分析类型中的键成为键的一部分,而不是值的一部分,以便化简器将接收分组在一起的一个分析作业的所有键,并且可以对值执行流式操作,而不必将它们保留在内存。

于 2013-10-10T15:38:58.403 回答