如何直接从mapper输出到HDFS?

时间:2012-04-23 23:38:04

标签: hadoop mapreduce

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

伪代码将是:

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

我觉得很难,因为我们唯一能玩的就是OutputCollector。 我想到的一件事是执行OutputCollector,覆盖OutputCollector.collect并执行这些操作。 有没有更好的方法?

4 个答案:

答案 0 :(得分: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.

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

但是,从mapper写入输出还有其他充分的理由。关于此问题有一个FAQ,但除了说你可以做之外,它的细节有点短。

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

答案 3 :(得分:0)

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

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

写入上下文

我想如果你能找到一些东西来把mapper中的数据写成你正在使用的语言的命名输出文件(例如:Python) - 这肯定会有效。

我希望这会有所帮助。