4

在某些条件下,我们希望 mapper 完成所有工作并输出到 HDFS,我们不希望将数据传输到 reducer(将使用额外的带宽,如果有错误请纠正我)。

一个伪代码是:

def mapper(k,v_list):
  for v in v_list:
    if criteria:
      write to HDFS
    else:
      emit

我发现这很难,因为我们唯一可以玩的是 OutputCollector。我想到的一件事是扩展 OutputCollector,覆盖 OutputCollector.collect 并做这些事情。有没有更好的方法?

4

4 回答 4

3

您可以使用 JobConf.setNumReduceTasks(0) 将 reduce 任务的数量设置为 0。这将使映射器的结果直接进入 HDFS。

来自 Map-Reduce 手册:http ://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html

Reducer NONE
It is legal to set the number of reduce-tasks to zero if no reduction is desired.

In this case the outputs of the map-tasks go directly to the FileSystem, 
into the output path set by setOutputPath(Path). The framework does not sort 
the map-outputs before writing them out to the FileSystem.
于 2012-04-24T00:39:22.250 回答
1

我假设您正在使用流媒体,在这种情况下,没有标准的方法可以做到这一点。

在 java Mapper 中这当然是可能的。对于流式传输,您需要修改 PipeMapper java 文件,或者像您说的编写自己的输出收集器 - 但如果您遇到这么多麻烦,您可能只需要编写一个 java 映射器。

于 2012-05-10T03:17:20.063 回答
0

如果您仍要将其写入 HDFS,则不向 Reducer 发送内容实际上可能不会节省带宽。HDFS 仍然被复制到其他节点并且复制将会发生。

不过,从映射器写入输出还有其他充分的理由。有一个关于这个的常见问题解答,但除了说你可以做到之外,它的细节有点短。

我在这里发现了另一个可能与您的问题重复的问题。如果您正在用 Java 编写 Mapper,那么该问题的答案会更有帮助。如果您尝试以流式方式执行此操作,则可以在脚本中使用 hadoop fs 命令来执行此操作。

于 2012-08-16T14:31:37.877 回答
0

事实上,我们可以将输出写入 HDFS 并同时将其传递给 Reducer。我知道您正在使用 Hadoop Streaming,我已经使用 Java MapReduce 实现了类似的东西。

我们可以使用 MultipleOutputs 从 Mapper 或 Reducer 生成命名输出文件。因此,在您的 Mapper 实现中,在处理输入数据的所有业务逻辑之后,您可以使用multipleOutputs.write("NamedOutputFileName", Outputkey, OutputValue)将输出写入 MultipleOutputs并且对于您想要传递给 reducer 的数据,您可以编写使用context.write(OutputKey, OutputValue)到上下文

我想如果你能找到一些东西来用你正在使用的语言(例如:Python)将数据从映射器写入一个命名的输出文件——这肯定会奏效。

我希望这有帮助。

于 2016-05-19T18:26:29.770 回答