2013-07-28 49 views
4

我已经编写了一个mapreduce程序来处理日志。作业除了将实际输出写入驱动程序代码中设置的输出路径外部的其他位置外,还将边数据写入。但是,执行启用,杀死任务尝试的输出不会被删除。是否有办法避免这个问题? 是否可以解决问题,而不是写入正常输出位置并在作业完成后复制到外部位置?使用Hadoop多输出写入多个输出启用推测执行

使用'OutputCommitter'可以解决这个问题吗?

有没有人试过吗?任何帮助,将不胜感激。

回答

1

是的,可以使用FileOutputCommitter在任务成功时将临时任务目录的内容移动到最终输出目录,并删除原始任务目录。

我相信Hadoop中扩展FileOutputFormat的大多数内置输出格式都使用OutputCommitter,默认情况下它是FileOutputCommitter。

这是FileOutputFormat

public synchronized 
    OutputCommitter getOutputCommitter(TaskAttemptContext context 
             ) throws IOException { 
    if (committer == null) { 
     Path output = getOutputPath(context); 
     committer = new FileOutputCommitter(output, context); 
    } 
    return committer; 
    } 

代码写入多个路径,你也许可以考虑MultipleOutputs,在默认情况下使用OutputCommitter。

或者你可以创建自己的输出格式和扩展FileOutputFomat和覆盖上述功能在FileOutputFormat,创建自己的OutputCommitter实现看FileOutputCommitter代码。

在FileOoutputcommitter代码,你会发现的功能,你可能会感兴趣的 - 如果一个任务,然后成功commitTask()被调用,它在默认 实现移动temporaray

/** 
    * Delete the work directory 
    */ 
    @Override 
    public void abortTask(TaskAttemptContext context) { 
    try { 
     if (workPath != null) { 
     context.progress(); 
     outputFileSystem.delete(workPath, true); 
     } 
    } catch (IOException ie) { 
     LOG.warn("Error discarding output" + StringUtils.stringifyException(ie)); 
    } 
    } 

任务输出目录(其名称中包含 任务尝试ID以避免任务 尝试之间的冲突)到最终输出路径$ {mapred.out put.dir}。否则, 框架调用abortTask(),它将删除临时任务 的输出目录。

+1

,我会尝试一下OutpurCommitter.I有一个查询。如果我需要在mapreduce作业中输出数据并减少任务,多个输出如何工作(键和值类型对于多个输出和正常输出)?如果我在地图任务中使用多个输出来输出数据,它会被写入地图任务本身还是会缩小以减少任务?键和值类型是否需要是通用的(即WritableComparable和Writable)? – InfamousCoconut

+0

它可以双向使用 - 如果您使用mapper中的mos.write(K key,V value,String baseOutputPath),其中baseOutputPath与path/keyname类似,您将获得路径/ keyname-m-0000x的输出。该输出不会被减少任务处理。 Reduce任务只会处理使用context.write()发出的密钥。您可以使用LazyOutputFormat模仿MultipleOutputFormat的行为,如MultipleOutputs的同一链接中所述。而且,是的,随着API的提及,MultipleOutputs中使用的键值必须是WritableComparable/Writable。 –

+0

。如果多输出位置设置为作业输出位置,我已经阅读了多个输出的问题。假设我在使用与作业输出相同位置的mapper和reducer中编写多个输出,它将如何表现?我会错过写入mapper阶段的数据吗? – InfamousCoconut

0

为了避免_logs和_SUCCESS文件映射精简输出文件夹中创建您可能会使用以下设置:
conf.setBoolean( “mapreduce.fileoutputcommitter.marksuccessfuljobs”,假); conf.set(“hadoop.job.history.user.location”,“none”);