分享

MapReduce中设置全局变量

hyj 2014-4-23 16:02:50 发表于 问题解答 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 7 73803
提示: 作者被禁止或删除 内容自动屏蔽

已有(7)人评论

跳转到指定楼层
pig2 发表于 2014-4-23 16:08:37
上面这个方法有一个限制:
conf.set()方法只能传递String类型的变量,如果在mapper或reducer中更合适使用别的类型(比如List,Map等),则需要通过一些方法来转换,而如果转换方法比较复杂或者数据量比较大,则对整个程序的效率会产生很大的影响,因为上面这种方法每次调用map函数都会进行同样的转换,这种重复性的工作是不可容忍的,并且也违反了我们使用全局变量的初衷。

替代的方法是将static变量定义为mapper类的成员变量,并在static块或static成员函数中进行初始化,这样整个mapper过程只需对static变量初始化一次,这对效率会有很大的提高。

程序结构如下:

        public class myMR{
          public static class myMapper extends Mapper<Text, Text, Text, Text>{
               private static Set<**> subglobal;
               //other static variable
               static{
                    //initialize 'subglobal'
               }
               //other static blocks
               public void map(Text key, Text value, Context context)
                                      throws IOException, InterruptedException{
                    //直接使用subglobal
               }
          }
          public static class myReducer extends Reducer<Text, Text, Text, Text>{
               public void reducer(Text key, Iterable<Text>, Context context)
                                     throws IOException, InterruptedException{
                     //reducer process
               }
          }
          public static void main(String[] args){
               //your job
          }

对java熟悉的话很容易就可以看出来,这只是个static对象初始化问题。但是这种方法使用的并不是mapper和reducer角度上的全局变量,而只是站在某个mapper task角度上的“全局变量”。而这种情况下除了使用static变量及其初始化块这种方法之外,还可以添加自定义的setup(Context)和close(Context)函数来初始化,这两个方法只在某mapper或reducer task开始和结束的时候分别调用一次,可以起到与上面代码所用方法一样的效果。

回复

使用道具 举报

hyj 发表于 2014-4-23 16:18:39
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

a553392350 发表于 2014-4-24 14:38:34
写的比较好,值得一看
回复

使用道具 举报

perfri 发表于 2014-4-27 23:29:52
值得一看的帖子,谢谢分享
回复

使用道具 举报

monkey131499 发表于 2015-1-6 10:11:57
学习了,正好遇到这方面问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条