我在Hadoop中编写了一些应该执行以下任务的代码:
在Mapper中:从输入拆分中逐个读取记录,并对它们执行一些处理。然后,根据完成的工作结果,某些记录被修剪并保存在集中。在映射器的 end 处,必须将此集发送到reducer。
在Reducer中:处理所有Mapper中收到的所有集合并生成最终结果。
我的问题是:如何延迟将所提到的集合发送到Reducer,直到处理每个映射器中的最后一条记录为止。默认情况下,Mapper中编写的所有代码都作为输入记录的数量运行(如果错误则更正);因此,多次将集合发送到reducer(作为输入记录的数量)。 如何识别每个映射器中输入拆分的处理结束?
(现在我使用带有计数器的if条件来计算已处理记录的数量,但我认为必须有更好的方法。另外如果我不知道文件中的记录总数,这种方法不起作用)
这是工作的流程图:
答案 0 :(得分:1)
如果您查看Mapper class(Javadoc),可以看到它有四种可用方法:
cleanup(org.apache.hadoop.mapreduce.Mapper.Context context)
map(KEYIN key, VALUEIN value, org.apache.hadoop.mapreduce.Mapper.Context context)
run(org.apache.hadoop.mapreduce.Mapper.Context context)
setup(org.apache.hadoop.mapreduce.Mapper.Context context)
run()
的默认实现如下:
public void run(Context context) throws IOException, InterruptedException {
setup(context);
try {
while (context.nextKeyValue()) {
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
} finally {
cleanup(context);
}
}
这说明了调用每个方法的顺序/时间。通常,您将覆盖map()
方法。可以使用setup()
和cleanup()
在映射器运行的开始/结束时完成一些工作。
代码显示,对于进入映射器的每个键/值对,将调用map()
方法一次。 setup()
和cleanup()
将在正在处理的键/值的开头和结尾处调用一次。
在您的情况下,当处理完所有键/值后,您可以使用cleanup()
输出一次值。