有没有办法从MR作业中的reduce任务访问多个成功的map任务?

时间:2011-11-04 13:20:18

标签: hadoop mapreduce

在我的Hadoop reducer 中,我需要知道在当前作业中执行了多少次成功的地图任务。我想出了以下内容,据我所知,它不起作用。

    Counter totalMapsCounter = 
        context.getCounter(JobInProgress.Counter.TOTAL_LAUNCHED_MAPS);
    Counter failedMapsCounter = 
        context.getCounter(JobInProgress.Counter.NUM_FAILED_MAPS);
    long nSuccessfulMaps = totalMapsCounter.getValue() - 
                           failedMapsCounter.getValue();

或者,如果有一种好的方法可以检索(再次,从我的 reducer 中)输入分割的总数(不是文件数,而不是一个文件的分割,但总数分开工作),这可能也会奏效。 (假设我的工作正常完成,那应该是相同的数字,对吗?)

2 个答案:

答案 0 :(得分:2)

编辑:在地图中检索计数器并使用Job或JobConf减少任务看起来不是一个好习惯。这是一个alternate approach,用于将汇总详细信息从映射器传递给reducer。这种方法需要一些代码的努力,但是可行。如果该功能是Hadoop的一部分并且不需要手动编码,那就太好了。我已经请求将此功能放入Hadoop并等待响应。


使用旧的MR API在Reducer类中使用以下代码检索了JobCounter.TOTAL_LAUNCHED_MAPS。

private String jobID;
private long launchedMaps;

public void configure(JobConf jobConf) {

    try {
        jobID = jobConf.get("mapred.job.id");

        JobClient jobClient = new JobClient(jobConf);

        RunningJob job = jobClient.getJob(JobID.forName(jobID));

        if (job == null) {
            System.out.println("No job with ID found " + jobID);
        } else {
            Counters counters = job.getCounters();
            launchedMaps = counters.getCounter(JobCounter.TOTAL_LAUNCHED_MAPS);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

使用新API,Reducer实施可以通过JobContext#getConfiguration()访问作业的配置。上述代码可以在Reducer#setup()中实现。

在调整Reducer.reduce()之前,为每个reduce任务调用旧MR API中的Reducer#configure()和新MR API中的Reducer#setup()。

顺便说一句,计数器可以从其他JVM中获得,也可以从那个工作中获得。

JobInProgress定义如下,因此不应使用它。此API仅适用于受限项目,界面可能会更改。

<强> @ InterfaceAudience.LimitedPrivate({ “MapReduce的”})
@ InterfaceStability.Unstable

不是这样,JobCounter.TOTAL_LAUNCHED_MAPS还包括由speculative execution启动的地图任务

答案 1 :(得分:1)

使用新API我检索了一个用户定义的计数器(Mapper中的Enum)和一个Inbuilt计数器。 这是我的reducer的代码:这是reducer的Setup方法。虽然我必须使用一些旧的API类(mapred包)

    JobContext jobContext= new JobContext(context.getConfiguration(), context.getJobID());
    Configuration c= jobContext.getConfiguration();

    jobID=c.get("mapred.job.id");
    //jobId= JobID.forName(jobID);

    JobClient jobClient = new JobClient(new JobConf(c));

    RunningJob job = jobClient.getJob((org.apache.hadoop.mapred.JobID) JobID.forName(jobID));

    Counters counters = job.getCounters();

    long customCounterCount= counters.getCounter(WordCountMapper.CustomCounters.COUNT);

    long totalMapInputRecords = counters.getCounter(Task.Counter.MAP_INPUT_RECORDS);

    System.out.println("customCounterCount==> " + customCounterCount);
    System.out.println("totalMapInputRecords==> " + totalMapInputRecords);