Hadoop中如何将Mapper的值上报给Driver程序?
How to report a value from Mapper to the Driver program in Hadoop?
我有一个 hadoop 程序,我想在映射器末尾向驱动程序报告一个值。因此,在驱动程序中我有多个值,每个值都来自映射器然后我想获得值之间的最大值。我正在使用 Counter 对其进行编码,这是我拥有的代码:
protected void cleanup(Context context){
....
context.getCounter("TimeStamps", "Max").setValue(value);
}
在驱动程序中我有
CounterGroup counters = job.getCounters().getGroup("TimeStamps");
Iterator<Counter> iter = counters.iterator();
while(iter.hasNext()){
Counter c = iter.next();
}
然而,只有值被报告回来(而不是多个值)。我应该怎么做才能让每个映射器报告一个单独的值并且我可以在驱动程序中获取它们?
有一种方法可以做到这一点(尽管我觉得这不是一种干净的方法)。
当您在映射器中发出计数器时,您可以获得任务尝试 ID 并以此作为计数器名称的前缀。
例如在 WordCount 程序的 map()
方法中,对于遇到的每个单词,我发出:
context.getCounter("ME", context.getTaskAttemptID() + ":MY_TOTAL").increment(1);
以上,ME
为计数器组。计数器名称是 Task Attempt ID
和 MY_TOTAL
.
的组合
例如映射任务尝试 ID 通常采用以下形式:task_1450681906391_0024_m_000000_0
(m_000000_0
用于作业中的第一个映射器)。
因此,此映射器的计数器名称将是:task_1450681906391_0024_m_000000_0:MY_TOTAL
。
不同映射器的类似计数器名称将是:
Mapper 2 => task_1450681906391_0024_m_000001_0:MY_TOTAL
Mapper 3 => task_1450681906391_0024_m_000002_0:MY_TOTAL
Mapper 4 => task_1450681906391_0024_m_000003_0:MY_TOTAL
现在,在驱动程序中,我在设置Job::waitForCompletion(true)
后添加了以下代码:
job.waitForCompletion(true);
CounterGroup counters = job.getCounters().getGroup("ME");
Iterator<Counter> iter = counters.iterator();
while(iter.hasNext()) {
Counter c = iter.next();
System.out.println(c.getName() + " " + c.getValue());
}
我 运行 1 GB 数据的字数统计程序,产生了 7 个映射器。程序成功执行后,得到如下输出:
attempt_1450681906391_0024_m_000000_0:MY_TOTAL 9318964
attempt_1450681906391_0024_m_000001_0:MY_TOTAL 9068018
attempt_1450681906391_0024_m_000002_0:MY_TOTAL 9241336
attempt_1450681906391_0024_m_000003_0:MY_TOTAL 9182102
attempt_1450681906391_0024_m_000004_0:MY_TOTAL 8948100
attempt_1450681906391_0024_m_000005_0:MY_TOTAL 8992634
attempt_1450681906391_0024_m_000006_0:MY_TOTAL 8564646
您可以看到,不同映射器的计数器是分开发出的。您可以轻松地解析出映射器并获取每个映射器的计数器,如下所示:
Mapper 1 => MY_TOTAL 9318964
Mapper 2 => MY_TOTAL 9068018
Mapper 3 => MY_TOTAL 9241336
Mapper 4 => MY_TOTAL 9182102
Mapper 5 => MY_TOTAL 8948100
Mapper 6 => MY_TOTAL 8992634
Mapper 7 => MY_TOTAL 8564646
我有一个 hadoop 程序,我想在映射器末尾向驱动程序报告一个值。因此,在驱动程序中我有多个值,每个值都来自映射器然后我想获得值之间的最大值。我正在使用 Counter 对其进行编码,这是我拥有的代码:
protected void cleanup(Context context){
....
context.getCounter("TimeStamps", "Max").setValue(value);
}
在驱动程序中我有
CounterGroup counters = job.getCounters().getGroup("TimeStamps");
Iterator<Counter> iter = counters.iterator();
while(iter.hasNext()){
Counter c = iter.next();
}
然而,只有值被报告回来(而不是多个值)。我应该怎么做才能让每个映射器报告一个单独的值并且我可以在驱动程序中获取它们?
有一种方法可以做到这一点(尽管我觉得这不是一种干净的方法)。
当您在映射器中发出计数器时,您可以获得任务尝试 ID 并以此作为计数器名称的前缀。
例如在 WordCount 程序的 map()
方法中,对于遇到的每个单词,我发出:
context.getCounter("ME", context.getTaskAttemptID() + ":MY_TOTAL").increment(1);
以上,ME
为计数器组。计数器名称是 Task Attempt ID
和 MY_TOTAL
.
例如映射任务尝试 ID 通常采用以下形式:task_1450681906391_0024_m_000000_0
(m_000000_0
用于作业中的第一个映射器)。
因此,此映射器的计数器名称将是:task_1450681906391_0024_m_000000_0:MY_TOTAL
。
不同映射器的类似计数器名称将是:
Mapper 2 => task_1450681906391_0024_m_000001_0:MY_TOTAL
Mapper 3 => task_1450681906391_0024_m_000002_0:MY_TOTAL
Mapper 4 => task_1450681906391_0024_m_000003_0:MY_TOTAL
现在,在驱动程序中,我在设置Job::waitForCompletion(true)
后添加了以下代码:
job.waitForCompletion(true);
CounterGroup counters = job.getCounters().getGroup("ME");
Iterator<Counter> iter = counters.iterator();
while(iter.hasNext()) {
Counter c = iter.next();
System.out.println(c.getName() + " " + c.getValue());
}
我 运行 1 GB 数据的字数统计程序,产生了 7 个映射器。程序成功执行后,得到如下输出:
attempt_1450681906391_0024_m_000000_0:MY_TOTAL 9318964
attempt_1450681906391_0024_m_000001_0:MY_TOTAL 9068018
attempt_1450681906391_0024_m_000002_0:MY_TOTAL 9241336
attempt_1450681906391_0024_m_000003_0:MY_TOTAL 9182102
attempt_1450681906391_0024_m_000004_0:MY_TOTAL 8948100
attempt_1450681906391_0024_m_000005_0:MY_TOTAL 8992634
attempt_1450681906391_0024_m_000006_0:MY_TOTAL 8564646
您可以看到,不同映射器的计数器是分开发出的。您可以轻松地解析出映射器并获取每个映射器的计数器,如下所示:
Mapper 1 => MY_TOTAL 9318964
Mapper 2 => MY_TOTAL 9068018
Mapper 3 => MY_TOTAL 9241336
Mapper 4 => MY_TOTAL 9182102
Mapper 5 => MY_TOTAL 8948100
Mapper 6 => MY_TOTAL 8992634
Mapper 7 => MY_TOTAL 8564646