在某些标准中,我们希望映射器完成所有工作并输出到HDFS,我们不希望将数据传输到reducer(将使用额外的带宽,如果有错误,请纠正我。)
伪代码将是:
def mapper(k,v_list):
for v in v_list:
if criteria:
write to HDFS
else:
emit
我觉得很难,因为我们唯一能玩的就是OutputCollector。 我想到的一件事是执行OutputCollector,覆盖OutputCollector.collect并执行这些操作。 有没有更好的方法?
答案 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) - 这肯定会有效。
我希望这会有所帮助。