我有大量的输入数据(这就是我使用Hadoop的原因),并且有多个任务可以通过各种MapReduce步骤解决,其中第一个映射器需要所有数据作为输入。
我的目标:尽快计算这些不同的任务。
我目前让他们按顺序运行所有数据中的每个读数。我假设在将任务和执行类似部分(例如将所有数据都提供给映射器)组合一次时,它会更快。
我想知道是否以及如何将这些任务结合起来。对于每个输入键/值对,映射器可以发出“超级密钥”,其包括任务ID和任务特定密钥数据以及值。这样,reducers将获得任务和特定于任务的键的键/值对,并且可以决定何时看到“超级键”对要包含的键和值执行哪个任务。
在伪代码中:
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步骤。
计算最终将在亚马逊的Elastic MapReduce上进行。所有任务都要在整个数据集上计算,并尽可能快。
答案 0 :(得分:2)
- 这是一种明智的做法吗?
除了维持不同工作逻辑的耦合之外,它没有任何内在错误。我相信它可以节省一些磁盘I / O,如果您的磁盘是您的进程的瓶颈,这可能是一个胜利(在小型集群上可能就是这种情况)。
- 有更好的选择吗?
编写一个有点框架的Mapper和Reducer可能是谨慎的,它们都接受作为配置参数的引用,它们应该推迟到实际映射和减少的类。这可以解决上面提到的代码耦合(也许你已经想过这个)。
- 它有一些可怕的缺点吗?
我唯一能想到的是,如果其中一个任务的映射逻辑未能及时完成其工作,则调度程序可以启动另一个节点来处理该输入数据;这可能会导致重复工作,但如果不了解您的流程,很难说这是否重要。同样适用于减速器。
- 我是否需要这种方法的自定义分区程序类?
可能,取决于你在做什么。我想一般来说,如果你正在编写一个自定义输出WritableComparable,你也需要自定义分区。可能有一些库Partitioner
可以根据您的需要进行配置(例如KeyFieldBasedPartitioner,如果您输出类型Text
并使用String
字段分隔符而不是滚动您的自己的)。
HTH。如果你能提供更多的背景,也许我可以提供更多的建议。祝你好运!
答案 1 :(得分:2)
您可以使用:
两者都用于在hadoop中编写工作流程。
答案 2 :(得分:0)
我认为Oozie是最好的选择。它是一个工作流程调度程序,您可以在其中组合多个hadoop作业,其中一个操作节点的输出将是下一个操作节点的输入。如果任何操作失败,那么下次再次执行时,调度程序将从遇到错误的位置开始。