我已经编写了一个mapreduce程序来处理日志。除了实际输出之外,作业还将副数据写入驱动程序代码中设置的输出路径外部的不同位置。但是启用推测执行后,被杀死的任务尝试的输出不是删除。有没有办法避免这个问题? 除了写入正常输出位置并在作业完成后复制到外部位置之外,是否可以解决问题?
使用'OutputCommitter'可以解决这个问题吗?
有人试过吗?任何帮助将不胜感激。
答案 0 :(得分: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。
或者您可以在FileOutputFormat中创建自己的输出格式并扩展FileOutputFomat和覆盖上述函数,创建自己的OutputCommitter实现,查看FileOutputCommitter代码。
在FileOoutputcommitter代码中,您将找到您可能感兴趣的函数 -
/**
* 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));
}
}
如果任务成功,则调用commitTask(),默认情况下 实现移动temporaray任务输出目录(具有 任务尝试ID在其名称中,以避免任务之间的冲突 尝试)到最终输出路径,$ {mapred.out put.dir}。除此以外, 框架调用abortTask(),删除临时任务 输出目录。
答案 1 :(得分:0)
要避免在mapreduce输出文件夹中创建_logs和_SUCCESS文件,您可以使用以下设置:
conf.setBoolean(“mapreduce.fileoutputcommitter.marksuccessfuljobs”,false);
conf.set(“hadoop.job.history.user.location”,“none”);