我有一个由许多小文件(平均每个30-40 MB(组成的数据集。我想通过MapReduce对它们运行分析,但是对于每个作业,映射器将再次读取文件,这会对I/O性能(开销等(造成沉重的负载。
我想知道是否可以使用映射器一次,为不同的减速器发出各种不同的输出?当我环顾四周时,我发现多个减速器是不可能的,但唯一可能的事情是工作链。但是,我想并行运行这些作业,而不是按顺序运行,因为它们都将使用相同的数据集作为输入并运行不同的分析。所以,总而言之,我想要的东西如下:
Reducer = Analytics1 /
映射器 - 化简器 = 分析2
Reducer = Analytics3 ...
这可能吗?或者您对解决方法有任何建议吗?请给我一些想法。再次读取这些小文件会给我的分析带来巨大的开销和性能降低。
提前感谢!
编辑:我忘了提到我正在使用带有YARN的Hadoop v2.1.0-beta。
您可以:
- 让您的减速器在同一通道/作业中执行所有分析 (1-3(。编辑:从您的评论中,我看到这种替代方案对您没有用,但我将其留在这里以供将来参考,因为在某些情况下可以这样做。
- 使用比MapReduce更通用的模型。例如,Apache Tez(仍然是一个孵化器项目(可用于您的用例。
关于Apache Tez的一些有用参考:
- 描述Apache YARN和相关项目的研究论文,包括Apache Tez。
- 几篇博客文章解释了 Tez 的模型。
编辑:增加了关于备选方案1的以下内容:
您还可以让映射器生成一个键,指示输出要发送到哪个分析过程。Hadoop会自动按此键对记录进行分组,并将它们全部发送到同一个化简器。映射器生成的值是<k,v>
形式的元组,其中键(k
(是你打算生成的原始键。因此,映射器生成<k_analytics, <k,v>>
记录。化简器具有读取密钥的化简器方法,并根据密钥调用适当的分析方法(在化简器类中(。这种方法会起作用,但前提是您的化简器不必处理大量数据,因为在执行分析过程时,您可能需要将其保存在内存中(在列表或哈希表中((因为<k,v>
元组不会按其键排序(。如果这不是您的化简器可以处理的事情,那么 @praveen-sripati 建议的自定义分区程序可能是一个值得探索的选项。
编辑:正如@judge-mental所建议的那样,替代方案1可以通过让映射器发出<<k_analytics, k>, value>
来进一步改进;换句话说,使分析类型中的键成为键的一部分,而不是值,以便化简器将接收一个分析作业的所有键分组在一起,并且可以对值执行流操作,而不必将它们保存在RAM中。
使用自定义分区程序可能是可能的。自定义分区程序会根据键将映射器的输出重定向到相应的化简器。因此,映射器输出的键将是 R1*、R2*、R3***。需要研究这种方法的优缺点。
如前所述,Tez是替代方案之一,但它仍处于孵化器阶段。