如何将多个Hadoop MapReduce作业合并成一个?

3

我有大量的输入数据(这就是为什么我使用Hadoop),有多个任务可以通过各种MapReduce步骤解决,其中第一个mapper需要所有数据作为输入。

我的目标:尽快计算完成这些不同的任务。

我目前让它们顺序运行,每个任务都会读取所有数据。我认为当组合任务并仅执行其相似部分(例如只将所有数据提供给Mapper)一次时,速度会更快。

我想知道如何以及如何将这些任务组合起来。对于每个输入键/值对,Mapper可以发出包括任务ID和任务特定键数据以及值的"超级键"。这样,Reducer将获得用于任务和任务特定键的键/值对,并且在看到"超级键"时可以决定对包含的键和值执行哪个任务。

伪代码如下:

map(key, value):
    emit(SuperKey("Task 1", IncludedKey), value)
    emit(SuperKey("Task 2", AnotherIncludedKey), value)

reduce(key, values):
   if key.taskid == "Task 1":
      for value in values:
          // do stuff with key.includedkey and value
   else:
      // do something else

这个关键字可以是一个WritableComparable,其中包含了所有必要的信息。

注意:伪代码建议的架构很糟糕,肯定有更聪明的方法。

我的问题是:

  • 这是一个明智的方法吗?
  • 是否有更好的替代方案?
  • 它有一些可怕的缺点吗?
  • 我需要为这种方法使用自定义的Partitioner类吗?

上下文:数据由数百万个RDF四元组组成,任务是计算聚类、统计和相似性。一些任务可以在Reducer中仅使用Hadoop计数器轻松解决,但有些任务需要多个MapReduce步骤。

计算最终将在Amazon的Elastic MapReduce上进行。所有任务都要在整个数据集上尽可能快地完成。

3个回答

2
  • 这是一个合理的方法吗?

除了维护不同作业逻辑的耦合之外,它本质上没有什么问题。我认为如果您的磁盘是流程的瓶颈(在小型集群上可能会出现),它将节省一些磁盘I / O,这可能是一个胜利。

  • 有更好的替代方案吗?

编写一个略微框架化的Mapper和Reducer,每个都接受作为配置参数对它们应该推迟到进行实际映射和缩减的类的引用,可能是明智的。这可以解决代码的耦合问题(也许您已经考虑过这一点)。

  • 它有什么可怕的缺点吗?

我所能想到的唯一问题是,如果其中一个任务的映射逻辑未能及时完成其工作,则调度程序可能会启动另一个节点来处理该输入数据的一部分。这可能导致重复的工作,但是如果不了解有关您的流程的更多信息,很难说这是否会产生太大影响。Reducers也是如此。

  • 我需要为此方法使用自定义的Partitioner类吗?

可能会,这取决于您正在做什么。我认为通常情况下,如果您正在编写自定义输出WritableComparable,则还需要自定义分区。但是,可能有一些库Partitioner可供配置以满足您的需求(例如KeyFieldBasedPartitioner,如果您将输出类型设置为

希望对你有所帮助。如果您能提供更多上下文,也许我可以提供更多建议。祝你好运!


到目前为止,非常感谢!我添加了更多的上下文信息,希望听到您的想法。 - stefanw

2
您可以使用以下两种工具:
  1. Cascading
  2. Oozie
这两种工具都用于在hadoop中编写工作流。

0

我认为Oozie是这个问题的最佳选择。它是一个工作流调度程序,可以将多个Hadoop作业组合在一起,其中一个操作节点的输出将成为下一个操作节点的输入。如果任何一个操作失败,那么下一次执行时,调度程序将从遇到错误的地方开始。

http://www.infoq.com/articles/introductionOozie


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接