1、通常作业的输入和输出都会被存储在文件系统中。 整个框架负责任务的调度和监控,以及重新执行已经失败的任务。通常,Map/Reduce框架和分布式文件系统是运行在一组相同的节点上的,也就是说,计算节点和存储节点通常在一起。这种配置允许框架在那些已经存好数据的节点上高效地调度任务,这可以使整个集群的网络带宽被非常高效地利用。Map/Reduce框架由一个单独的masterJobTracker和每个集群节点一个slaveTaskTracker共同组成。master负责调度构成一个作业的所有任务,这些任务分布在不同的slave上,master监控它们的执行,重新执行已经失败的任务。而slave仅负责执行
2、由master指派的任务。应用程序至少应该指明输入/输出的位置(路径),并通过实现合适的接口或抽象类提供map和reduce函数。再加上其他作业的参数,就构成了作业配置(job configuration)。然后,Hadoop的job client提交作业(jar包/可执行程序等)和配置信息给JobTracker,后者负责分发这些软件和配置信息给slave、调度任务并监控它们的执行,同时提供状态和诊断信息给job-client。虽然Hadoop框架是用Java实现的,但Map/Reduce应用程序则不一定要用 Java来写 。2.样例分析:单词计数1、WordCount源码分析单词计数是最简单
3、也是最能体现MapReduce思想的程序之一,该程序完整的代码可以在Hadoop安装包的src/examples目录下找到单词计数主要完成的功能是:统计一系列文本文件中每个单词出现的次数,如图所示:(1)Map过程Map过程需要继承org.apache.hadoop.mapreduce包中的Mapper类,并重写map方法通过在map方法中添加两句把key值和value值输出到控制台的代码,可以发现map方法中的value值存储的是文本文件中的一行(以回车符作为行结束标记),而key值为该行的首字符相对于文本文件的首地址的偏移量。然后StringTokenizer类将每一行拆分成一个个的单词,
4、并将作为map方法的结果输出,其余的工作都交由MapReduce框架处理。其中IntWritable和Text类是Hadoop对int和string类的封装,这些类能够被串行化,以方便在分布式环境中进行数据交换。TokenizerMapper的实现代码如下:12345678910121314public static class TokenizerMapper extends Mapperprivate final static IntWritable one = new IntWritable(1);private Text word = new Text();public void map
5、(Object key, Text value, Context context) throws IOException, InterruptedException System.out.println(key = + key.toString();/添加查看key值value = + value.toString();/添加查看value值StringTokenizer itr = new StringTokenizer(value.toString();while (itr.hasMoreTokens() word.set(itr.nextToken();context.write(wor
6、d, one);(2)Reduce过程Reduce过程需要继承org.apache.hadoop.mapreduce包中的Reducer类,并重写reduce方法reduce方法的输入参数key为单个单词,而values是由各Mapper上对应单词的计数值所组成的列表,所以只要遍历values并求和,即可得到某个单词的出现总次数IntSumReduce类的实现代码如下:public static class IntSumReducer extends Reducer private IntWritable result = new IntWritable();public void reduc
7、e(Text key, Iterable values, Context context) throws IOException, InterruptedException int sum = 0;for (IntWritable val : values) sum += val.get();result.set(sum);context.write(key, result);(3)执行MapReduce任务在MapReduce中,由Job对象负责管理和运行一个计算任务,并通过Job的一些方法对任务的参数进行相关的设置。此处设置了使用TokenizerMapper完成Map过程和使用的IntS
8、umReduce完成Combine和Reduce过程。还设置了Map过程和Reduce过程的输出类型:key的类型为Text,value的类型为IntWritable。任务的输入和输出路径则由命令行参数指定,并由FileInputFormat和FileOutputFormat分别设定。完成相应任务的参数设定后,即可调用job.waitForCompletion()方法执行任务,主函数实现如下:1516171819public static void main(String args) throws Exception Configuration conf = new Configuration
9、();String otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();if (otherArgs.length != 2) System.err.println(Usage: wordcount );System.exit(2);Job job = new Job(conf, word countjob.setJarByClass(wordCount.class);job.setMapperClass(TokenizerMapper.class);job.setCombinerClass(IntSumRedu
10、cer.class);job.setReducerClass(IntSumReducer.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);FileInputFormat.addInputPath(job, new Path(otherArgs0);FileOutputFormat.setOutputPath(job, new Path(otherArgs1);System.exit(job.waitForCompletion(true) ? 0 : 1);运行结果如下:14/
11、12/17 05:53:26 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId=26 INFO input.FileInputFormat: Total input paths to process : 226 INFO mapred.JobClient: Running job: job_local_000126 INFO mapred.MapTask: io.sort.mb = 10027 INFO mapred.MapTask: data buffer = 796917
12、76/99614720 record buffer = 262144/327680key = 0value = Hello Worldkey = 12value = Bye World Starting flush of map output Finished spill 027 INFO mapred.TaskRunner: Task:attempt_local_0001_m_000000_0 is done. And is in the process of commiting27 INFO mapred.LocalJobRunner: Task attempt_local_0001_m_
13、000000_0 done.value = Hello Hadoopkey = 13value = Bye Hadoopattempt_local_0001_m_000001_0 is done. And is in the process of commiting Task attempt_local_0001_m_000001_0 done.27 INFO mapred.Merger: Merging 2 sorted segments Down to the last merge-pass, with 2 segments left of total size: 73 bytesatte
14、mpt_local_0001_r_000000_0 is done. And is in the process of commiting Task attempt_local_0001_r_000000_0 is allowed to commit now27 INFO output.FileOutputCommitter: Saved output of task attempt_local_0001_r_000000_0 to out reduce reduce Task attempt_local_0001_r_000000_0 done.27 INFO mapred.JobClien
15、t: map 100% reduce 100% Job complete: Counters: 14 FileSystemCounters FILE_BYTES_READ=17886 HDFS_BYTES_READ=52932 FILE_BYTES_WRITTEN=54239 HDFS_BYTES_WRITTEN=71431 Map-Reduce Framework Reduce input groups=4 Combine output records=6 Map input records=4 Reduce shuffle bytes=0 Reduce output records=4 S
16、pilled Records=12 Map output bytes=78 Combine input records=8 Map output records=8 Reduce input records=62、WordCount处理过程上面给出了WordCount的设计思路和源码,但是没有深入细节,下面对WordCount进行更加详细的分析:(1)将文件拆分成splits,由于测试用的文件较小,所以每一个文件为一个split,并将文件按行分割成对,如图,这一步由Mapreduce框架自动完成,其中偏移量包括了回车所占的字符(2)将分割好的对交给用户定义的map方法进行处理,生成新的对(3)
17、得到map方法输出的对后,Mapper会将它们按照key值进行排序,并执行Combine过程,将key值相同的value值累加,得到Mapper的最终输出结果,如图:(4)Reduce先对从Mapper接收的数据进行排序,再交由用户自定义的reduce方法进行处理,得到新的对,并作为WordCount的输出结果,如图:3.MapReduce,你够了解吗?MapReduce框架在幕后默默地完成了很多的事情,如果不重写map和reduce方法,会出现什么情况呢?下面来实现一个简化的MapReduce,新建一个LazyMapReduce,该类只对任务进行必要的初始化及输入/输出路径的设置,其余的参数
18、均保持默认代码如下:public class LazyMapReduce / TODO Auto-generated method stubif(otherArgs.length !wordcountLazyMapReduceFileInputFormat.addInputPath(job, new Path(args0);FileOutputFormat.setOutputPath(job, new Path(args1);System.exit(job.waitForCompletion(true)? 0:1);运行结果为:14/12/17 23:04:13 INFO jvm.JvmMetrics:14 INFO input.FileInputFormat:14 INFO mapred.JobClient:14 INFO mapred.MapTask:15 INFO mapred.JobClient: map 0% reduce 0%18 INFO mapred.MapTask:19 INFO mapred.MapTask:19 INFO mapred.TaskRunner:19 INFO mapred.LocalJobRunner:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1