hadoop mapreduce学习 Client部分
Mapreduce framework 同hdfs架构有类似的部分,分为JobTracker(对应Namenode),TaskTracker(对应Datanode),Job(对应DFSClient)。功能虽然不太相同,但是原理还接近。
总结一下Job的流程。Job是对JobClient的封装,Job本身功能比较简单,无非是获得各种参数,将参数封装好,向JobTracker提交job的过程。但是JobClient内部还是有些流程的。
1、在提交Job时候,首先JobClient向JobTracker要求获得一个unique的ID,即JobID
JobID jobId = jobSubmitClient.getNewJobId();
2、然后调用copyAndConfigureFiles函数,将所有需要的文件,以及第三方的lib都考入到distribuedCache中。同时将mapreduce需要操作的jar文件拷到底层的hdfs中,拷贝10份。
Path submitJarFile = JobSubmissionFiles.getJobJar(submitJobDir); job.setJar(submitJarFile.toString()); fs.copyFromLocalFile(new Path(originalJarPath), submitJarFile); fs.setReplication(submitJarFile, replication); fs.setPermission(submitJarFile, new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION));
3、下一步就需要对input path中也就是说需要处理的数据进行split(切分),每一个split对应一个map task,每个split又包含了许多的record(由key-value)组成。split只是逻辑上的概念,并不是真正的数据split,split结束确定每个split的位置(把BlockLocation对象包了一层),以及split的个数。比如FileInputFormat类中对File进行了split,过程为:
long bytesRemaining = length; while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) { int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining); splits.add(new FileSplit(path, length-bytesRemaining, splitSize, blkLocations[blkIndex].getHosts())); bytesRemaining -= splitSize; }
split结束后需要将split的元数据(即split切分结果)写入到hdfs中。
public static <T extends InputSplit> void createSplitFiles(Path jobSubmitDir, Configuration conf, FileSystem fs, T[] splits) throws IOException, InterruptedException { FSDataOutputStream out = createFile(fs, JobSubmissionFiles.getJobSplitFile(jobSubmitDir), conf); SplitMetaInfo[] info = writeNewSplits(conf, splits, out); out.close(); writeJobSplitMetaInfo(fs,JobSubmissionFiles.getJobSplitMetaFile(jobSubmitDir), new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION), splitVersion, info); }
至此split结束,返回值为切分个数,即map task个数。
4、最后将conf.xml拷贝到hdfs中,向jobTrakcer提交该Job,至此Job才真正提交。返回一个NetworkedJob,表明一个提交了的Job,通过该类来获取已经提交Job的所有信息。
所有的job 提交的jar file 和xml,以及job.split和job.splitmetainfo都存放在staging文件夹下,我存放的位置是/user/hadoop/.staging/ 需要有权限才能查看。其中jar file和job.split file都是有10个副本。
总结一下:在Job提交之前,所有需要拷贝的文件都已经拷贝到dfs中,split已经切分好。