在我的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 中)输入分割的总数(不是文件数,而不是一个文件的分割,但总数分开工作),这可能也会奏效。 (假设我的工作正常完成,那应该是相同的数字,对吗?)
答案 0 :(得分:2)
编辑:在地图中检索计数器并使用Job或JobConf减少任务看起来不是一个好习惯。这是一个alternate approach,用于将汇总详细信息从映射器传递给reducer。这种方法需要一些代码的努力,但是可行。如果该功能是Hadoop的一部分并且不需要手动编码,那就太好了。我已经请求将此功能放入Hadoop并等待响应。
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);