分享

MR中的Context类到底是谁?

tonydu 发表于 2016-12-16 17:34:43 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 4 18500
MR中的Context类到底是谁?

最近在学习MR编程,但是对Context类(如下代码标红处)始终没能真正的理解。

public void map(Object key, Textvalue, Context context) throws IOException,InterruptedException{

}

public void reduce(Text key, Iterable<IntWritable> values, Context context)  throws IOException,InterruptedException {

}

通过百度,有po主解释:
可以了解到,context应该是用来传递数据以及其他运行状态信息,map中的key、value写入context,让它传递给Reducer进行reduce,而reduce进行处理之后数据继续写入context,继续交给Hadoop写入hdfs系统。
从继承结构可以看出MapContext与ReduceContext均继承TaskInputOutputContext,没有重写继承而来的方法,所以它们继承的都是一致的
继承结构如下:
java.lang.object
   org.apache.hadoop.mapreduce.JobContext
        org.apache.hadoop.mapreduce.TaskAttemptContext
             org.apache.hadoop.mapreduce.TaskInputOutputContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
             ----write()方法: void  write (KEYOUT key,VALUEOUT value)
                    org.apache.hadoop.mapreduce.MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
                    org.apache.hadoop.mapreduce.ReduceContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

以上解释的出处: http://blog.csdn.net/songchunhong/article/details/50435717

但是这个解释好像不能解释下面的用法:
map类中:
context.write(new Text(vs), new Text(vs[j]));
context.write(new Text(vs[j]), new Text(vs));

这里为什么要Text类型?或者IntWritable类型?只是因为他们是序列化的??
我觉得这里的问题归结于: void write (KEYOUT key,VALUEOUT value) 中KEYOUT和VALUEOUT到底是什么类型??

reduce类中:
context.getConfiguration().get("count");

在上面po主解释的继承结构的各个类中找了好久,没找到getConfiguration()方法???


有点混沌,请路过的大神指点一下。


已有(4)人评论

跳转到指定楼层
langke93 发表于 2016-12-16 18:02:13
其实context如果刚开始学还是比较难以理解的。特别是没有编程经验的话。首先context他是一个类。如果有兴趣可以阅读源码
类中有函数。比如我们定义一个Dog类,他的方法是bark()和hungry()
public class Dog{


    void bark(){  // 汪汪叫
        System.out.println("汪汪,不要过来");
    }

    void hungry(){  // 饥饿
        System.out.println("主人,我饿了");
    }
}

而同样context也是一个类,他的方法很多,不止楼上列举的方法,其中包括write(),getConfiguration()方法。当然他们也是有参数的,而这个参数,也是定义好的。
明白上面问题,我们来回答楼主的问题:

我觉得这里的问题归结于: void write (KEYOUT key,VALUEOUT value) 中KEYOUT和VALUEOUT到底是什么类型??

他是什么类型,要看,你调用的哪个函数,并且应该有重载的函数,既然重载,可能比如:KEYOUT可能是整型,text型等等。

在上面po主解释的继承结构的各个类中找了好久,没找到getConfiguration()方法???

文章只是简单的画出来,还有更多的方法,楼主可以参考源码

获取源码,可以参考下面

从零教你如何获取hadoop2.4源码并使用eclipse关联hadoop2.4源码
http://www.aboutyun.com/thread-8211-1-1.html

推荐文章
hadoop开发必读:认识Context类的作用










回复

使用道具 举报

tonydu 发表于 2016-12-16 18:34:24
首先,谢谢这么详细的解释。其实,Context是个类,我果断知道的。我发这个帖子就是为了找其源码,但是在API中一直没找到这个类呀,所以只好求助各位大神。在你给的第二个连接中说,Context类是个内部类,也许这是我想要的。Anyway, thank you so much.
回复

使用道具 举报

beqiang 发表于 2017-10-13 10:22:00
最近刚准备学习大数据。这两天研究了下Mapper及其相关类的源码,版本为hadoop-2.7.2,以下是我的一些猜测,楼主可以参考下。
在自定义map类时map方法使用context这个变量,这个变量的类型是Mapper的一个内部类,我们可以用context输出map结果,获取配置参数值等,学过java的应该知道面向对象的一个特性,多态。这个Context类还有一个同名子类。我们在map阶段几个方法中输入参数确实是用Mapper类的内部类Context类型接收,但是我觉得传入的实例其实是这个子类Context实例。 1.png
原因:
在子类Context源码中,可以发现一个MapContext类型的mapContext属性,Context的方法内部其实都是调用这个mapContext的一些方法。这里mapContext属性我觉得仍然是运用了多态,父类引用子类实例。真正的实例其实是MapContext的子类MapContextImpl。
2.png
在这个类中,可以发现很多map阶段需要用到的属性,输入分片,RecordReader,Configuration等。这就解释了context如何作为map阶段的上下文对象,因为它可以获取这些关键诸如RecordReader的实例。
3.png
楼主所说的context的write 方法的输入类型的问题,还记得我们自定义mapper类继承Mapper时需要使用泛型指定输入key,输入value,输出key,输出value吗,查看子类Context发现其继承Mapper,其write方法的输入参数类型用的就是Mapper类声明的输出key,输出value的类型。

4.png
回复

使用道具 举报

evababy 发表于 2017-10-24 14:33:41
就是一个当前环境信息,或者叫运行环境,其中的write参数类型=继承类的输出kye/value
回复

使用道具 举报

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

本版积分规则

关闭

推荐上一条 /2 下一条