2013-01-07 51 views
1

我有一个要求,我想分享一个映射器和减速器类之间的变量。 情景如下: -如何在Mapper和Reducer类中共享一个变量?

假设我的输入记录类型为A,B和C.我正在处理这些记录,并相应地为map函数中的output.collect生成键和值。但同时我还在mapper类中声明了3个静态int变量,以保持记录A,B和C的类型的计数。现在,这些变量将由各种地图线程更新。当所有的地图任务完成后,我想将这三个值传递给Reduce函数。

这是如何实现的?我尝试重写close()方法,但是在所有地图函数执行完毕后,将在每个地图函数执行后调用它。或者有没有其他的方式来分享变量。我希望输出每种记录的总数以及我显示的任何处理输出。

回答

3

计数器出于特定的原因,即。以保持某些特定状态的计数,例如“NUMBER_OF_RECORDS_DISCARDED”。我相信只有增量这些计数器并没有设置为任意值(我可能在这里是错误的)。但是确定它们可以用作消息传递者,但是有一个更好的方法,那就是使用作业配置来设置变量并且无缝地进行。但是,这只能用于将自定义消息传递给映射器或缩减器,并且映射器中的更改将无法在reducer中使用。

使用旧设置消息/可变mapred API

JobConf job = (JobConf) getConf(); 
job.set("messageToBePassed-OR-anyValue", "123-awesome-value :P"); 

使用新的MapReduce API设置消息/变量:

Configuration conf = new Configuration(); 
conf.set("messageToBePassed-OR-anyValue", "123-awesome-value :P"); 
Job job = new Job(conf); 

使用获取消息/变量Mapper和Reducer中的旧API: configure()必须在Mapper和Reducer类和值可能会被分配给一个类成员,以便在内部使用map()reduce()

... 
private String awesomeMessage; 
public void configure(JobConf job) { 
    awesomeMessage = Long.parseLong(job.get("messageToBePassed-OR-anyValue")); 
} 
... 

变量awesomeMessage然后可以与地图和减少功能一起使用。

使用新的API中的映射和减速获取消息/变量: 类似的事情必须在设置()在这里完成。

Configuration conf = context.getConfiguration(); 
String param = conf.get("messageToBePassed-OR-anyValue"); 
+2

我敢肯定你不能传递映射器设置减速机配置状态 - 工作的conf复制并更新各的map/reduce任务,并在每个任务的最终配置不“解析'并保存回作业追踪器供以后使用。因此,尽管您可以在作业提交时设置配置,但无法全局更新或保留map/reduce任务中的新值 –

+0

我正在使用其映射函数没有上下文的org.apache.hadoop.mapred.Mapper;但记者的对象。 – Nilesh

+0

是的,谢谢你指出克里斯。你是绝对正确的。我的错。 – Amar

1

得到了解决方案。

用过的计数器。记者级在Mapper和Reducer中都可以访问。