超人学院

Hadoop源代码分析(包hadoop.mapred中的MapReduce接口)

对着背影说爱祢 提交于 2019-11-27 07:39:06
前面已经完成了对org.apache.hadoop.mapreduce的分析,这个包提供了Hadoop MapReduce部分的应用API,用于用户实现自己的MapReduce应用。但这些接口是给未来的MapReduce应用的,目前MapReduce框架还是使用老系统(参考补丁 HADOOP-1230 )。下面我们来分析org.apache.hadoop.mapred,首先还是从mapred的MapReduce框架开始分析,下面的类图(灰色部分为标记为@Deprecated的类/接口): 我们把包mapreduce的类图附在下面,对比一下,我们就会发现,org.apache.hadoop.mapred中的MapReduce API相对来说很简单,主要是少了和Context相关的类,那么,好多在mapreduce中通过context来完成的工作,就需要通过参数来传递,如Map中的输出,老版本是: output .collect(key,result); // output’s type is:OutputCollector 新版本是: context .write(key, result); // output’s type is: Context 它们分别使用 OutputCollector 和 Mapper.Context 来输出 map 的结果,显然,原有

Hadoop源代码分析(Task的内部类和辅助类)

你离开我真会死。 提交于 2019-11-26 19:52:49
从前面的图中,我们可以发现Task有很多内部类,并拥有大量类成员变量,这些类配合Task完成相关的工作,如下图。 MapOutputFile管理着Mapper的输出文件,它提供了一系列get方法,用于获取Mapper需要的各种文件,这些文件都存放在一个目录下面。 我们假设传入MapOutputFile的JobID为job_200707121733_0003,TaskID为task_200707121733_0003_m_000005。MapOutputFile的根为 {mapred.local.dir}/taskTracker/jobcache/{jobid}/{taskid}/output 在下面的讨论中,我们把上面的路径记为{MapOutputFileRoot} 以上面JogID和TaskID为例,我们有: {mapred.local.dir}/taskTracker/jobcache/job_200707121733_0003/task_200707121733_0003_m_000005/output 需要注意的是,{mapred.local.dir}可以包含一系列的路径,那么,Hadoop会在这些根路径下找一个满足要求的目录,建立所需的文件。MapOutputFile的方法有两种,结尾带ForWrite和不带ForWrite,带ForWrite用于创建文件

Hadoop源代码分析(*IDs类和*Context类)

谁说胖子不能爱 提交于 2019-11-26 19:52:39
我们开始来分析Hadoop MapReduce的内部的运行机制。用户向Hadoop提交Job(作业),作业在JobTracker对象的控制下执行。Job被分解成为Task(任务),分发到集群中,在TaskTracker的控制下运行。Task包括MapTask和ReduceTask,是MapReduce的Map操作和Reduce操作执行的地方。这中任务分布的方法比较类似于HDFS中NameNode和DataNode的分工,NameNode对应的是JobTracker,DataNode对应的是TaskTracker。JobTracker,TaskTracker和MapReduce的客户端通过RPC通信,具体可以参考HDFS部分的分析。 我们先来分析一些辅助类,首先是和ID有关的类,ID的继承树如下: 这张图可以看出现在Hadoop的org.apache.hadoop.mapred向org.apache.hadoop.mapreduce迁移带来的一些问题,其中灰色是标注为@Deprecated的。ID携带一个整型,实现了WritableComparable接口,这表明它可以比较,而且可以被Hadoop的io机制串行化/解串行化(必须实现compareTo/readFields/write方法)。JobID是系统分配给作业的唯一标识符,它的toString结果是job_

Hadoop源代码分析(MapTask辅助类 I)

拈花ヽ惹草 提交于 2019-11-26 19:52:18
Hadoop源代码分析(MapTask辅助类 I) MapTask的辅劣类主要针对Mapper的输入和输出。首先我们来看MapTask中用的的Mapper输入,在类图中,返部分位于右上角。 MapTask.TrackedRecordReader是一个Wrapper,在原有输入RecordReader的基础上,添加了收集上报统计数据的功能。 MapTask.SkippingRecordReader也是一个Wrapper,它在MapTask.TrackedRecordReader的基础上,添加了忽略部分输入的功能。在分析MapTask.SkippingRecordReader乊前,我们先看一下类SortedRanges和它相关的类。 类SortedRanges.Ranges表示了一个范围,以开始位置和范围长度(返样的话就可以表示长度为0的范围)来表示一个范围,并提供了一系列的范围操作方法。注意,方法getEndIndex得到的右端点并不包含在范围内(应理解为开区间)。SortedRanges包吨了一系列不重叠的范围,为了保证包吨的范围不重叠,在add方法和remove方法上需要做一些处理,保证不重叠的约束。SkipRangeIterator是访问SortedRanges包吨的Ranges的迭代器。 MapTask.SkippingRecordReader的实现径简单

Hadoop源代码分析(MapTask)

我只是一个虾纸丫 提交于 2019-11-26 19:52:06
接下来我们来分析Task的两个子类,MapTask和ReduceTask。MapTask的相关类图如下: MapTask其实不是很复杂,复杂的是支持MapTask工作的一些辅助类。MapTask的成员变量少,只有split和splitClass。我们知道,Map的输入是split,是原始数据的一个切分,这个切分由org.apache.hadoop.mapred.InputSplit的子类具体描述(前面我们是通过org.apache.hadoop.mapreduce.InputSplit介绍了InputSplit,它们对外的API是一样的)。splitClass是InputSplit子类的类名,通过它,我们可以利用Java的反射机制,创建出InputSplit子类。而split是一个BytesWritable,它是InputSplit子类串行化以后的结果,再通过InputSplit子类的readFields方法,我们可以回复出对应的InputSplit对象。 MapTask最重要的方法是run。run方法相当简单,配置完系统的TaskReporter后,就根据情况执行runJobCleanupTask,runJobSetupTask,runTaskCleanupTask或执行Mapper。由于MapReduce现在有两套API,MapTask需要支持这两套API

Hadoop源代码分析(MapTask辅助类,III)

不打扰是莪最后的温柔 提交于 2019-11-26 11:06:23
接下来讨论的是key,value的输出,这部分比较复杂,不过有了前面kvstart,kvend和kvindex配合的分析,有利于我们理解返部分的代码。 输出缓冲区中,和kvstart,kvend和kvindex对应的是bufstart,bufend和bufmark。这部分还涉及到变量bufvoid,用与表明实际使用的缓冲区结尾(见后面BlockingBuffer.reset分析),和变量bufmark,用于标记记录的结尾。返部分代码需要bufmark,是因为key戒value的输出是变长的,(前面元信息记录大小是常量,就不需要这样的变量)。 最好的情况是缓冲区没有翻转和value串行化结果很小,如下图: 先对key串行化,然后对value做串行化,临时变量keystart,valstart和valend分删记录了key结果的开始位置,value结果的开始位置和value结果的结束位置。 串行化过程中,往缓冲区写是最终调用了Buffer.write方法,我们后面再分析。 如果key串行化后出现bufindex < keystart,那么会调用BlockingBuffer的reset方法。原因是在spill的过程中需要对<key,value>排序,这种情况下,传递给RawComparator的必须是连续的二迕制缓冲区,通过BlockingBuffer.reset方法,解决返个问题