2013-10-10 47 views
6

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

我想知道是否可以使用一次映射器,为不同的reducer发出各种不同的输出?当我环顾四周时,我看到多个减速器是不可能的,但只有可能的事情是工作链。但是,我希望并行运行这些作业,而不是按顺序执行这些作业,因为它们都将相同的数据集用作输入并运行不同的分析。所以,综上所述,我想的东西是一样的东西如下:

 Reducer = Analytics1 
    /

映射 - 减速= Analytics2

 \ 
     Reducer = Analytics3 
       ... 

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

在此先感谢!

编辑:我忘了提及我在YARN上使用Hadoop v2.1.0-beta。

+0

您可以让您的Reducer在相同的通行证/工作中完成所有的Analytics(1-3)。 – cabad

+1

但是每个减速器可能会采取不同的输入(对)。因此,只有一个reducer中运行所有分析不适用于我。 Mapper应该针对不同的还原器(分析)发出不同的对。另外,在不同的对中,我希望能够从减速器之前发生的Shuffle&Sort机制中受益。 –

回答

3

您可以:

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

在Apache TEZ一些有用的参考文献:

编辑:增加了以下关于选择1:

你也可以将映射器生成一个密钥,指示将分析处理输出的目的。 Hadoop会通过此键自动对记录进行分组,并将它们全部发送给同一个reducer。映射器生成的值将是一个形式为<k,v>的元组,其中密钥(k)是您打算生成的原始密钥。因此,映射器会生成<k_analytics, <k,v>>记录。 reducer有一个读取关键字的reducer方法,并根据关键字调用相应的分析方法(在reducer类中)。这种方法是行得通的,但前提是你的简化者不必处理大量的数据,因为当你执行分析过程时,你可能需要将它保存在内存中(在列表或散列表中)(如<k,v>元组不会被按键排序)。如果这不是你的reducer可以处理的事情,那么@ praveen-sripati建议的自定义分区程序可能是一个探索的选项。

编辑:根据@ judge-mental的建议,可以通过让mappers问题<<k_analytics, k>, value>进一步改善替代方案1;换句话说,在键的分析类型部分(而不是值)中创建键,以便Reducer可以接收组合在一起的一个分析作业的所有键,并且可以对这些值执行流操作,而无需保留它们内存。

+0

我正处于一个项目的中间,目前看起来很难改变这种技术。有没有办法用原始Hadoop MapReduce来做到这一点? –

+0

我不这么认为。但是,如果您使用YARN(Hadoop 0.23或2.x),那么您可以轻松使用Tez,因为它在YARN之上工作。 Hadoop解耦了MapReduce,因此MapReduce现在可以在YARN之上实现,Tez和其他模型也是如此。 – cabad

+2

我相信您应该从映射器为您的1.替代项发出的元组是<< analytics_type,k_for_that_type>,v>。您的映射器会写入3条记录,而不是1条记录,并且最终的组数为3倍,但您可以从关键字中了解它属于哪种分析类型,从而可以在组上运行哪种类型的归约算法(以及在哪里放置输出)。这可以用普通的旧mapreduce来完成。 –

3

它可能通过使用custom partitioner。自定义分区程序将根据密钥将映射器的输出重定向到适当的reducer。因此,映射器输出的关键是R1 * ,R2 *,R3 ***。需要研究这种方法的优点和缺点。

如前所述,Tez是其中一个替代方案,但它仍处于孵化阶段。

+0

我的一些分析已经需要一个复合键方法,所以我将它用作<(k1,k2), v>。自定义分区程序已经在我的情况下实现了。是否有可能将此方法扩展到进一步的组合?我的数据非常庞大,所以我不想将所有内容都保存在内存中并处理。由于我需要组和排序机制,我使用混合键和排序阶段。 –

相关问题