Hadoop提供了最简单的Map/Reduce编程实例WordCount,本文对该Demo的程序结构,以及Map/Reduce框架的注意事项,进行了分析。

值得注意的一点是,Hadoop仍在不断的衍化中,本文的例子针对的是版本0.18.3。Release不久的0.20.0对Mapper/Reducer接口已经有所变化,不过影响不大。

Class Name: WordCount
   extends Configured implements Tool
   实现Tool接口的目的,是为了支持org.apache.hadoop.util.GenericOptionsParser的使用
   实现run(): 通过ToolRunner.run()可以Invoke这个方法。
   接口定义:public int run(String[] args) throws Exception {}
   流程:
   1. load配置:JobConf conf = new JobConf(getConf(), WordCount.class);
   配置是通过-conf参数传入,没有的话,采用默认配置。
   JobConf extends Configuration

   2.设置JobConf的一些成员
   conf.setJobName("wordcount");
   conf.setMapperClass(MapClass.class); 
   conf.setCombinerClass(Reduce.class);
   conf.setReducerClass(Reduce.class);
   conf.setNumMapTasks(); // 实际的Map Task数目由Job Tracker根据Cluster情况确定,不一定跟设置相同
   conf.setNumReduceTasks();
   conf.setInputFormat(TextInputFormat.class);
   conf.setOutputFormat(TextOutputFormat.class);
   conf.setOutputKeyClass(Text.class);
   conf.setOutputValueClass(IntWritable.class);

   3. 设置输入、输出的Path
   FileInputFormat.setInputPaths(conf, "HDFS PATH");
   FileOutputFormat.setOutputPath(conf, "HDFS PATH");

   4. 提交Job
   JobClient.runJob(conf);
   JobClient是用户Job跟JobTracker交互的接口,可以用来提交Job、跟踪Job进度、访问Task日志、获取Map-Reduce cluster状态信息。
   Job提交会进行如下操作:
   1) 检查Job的输入、输出specifications。
   2) 计算Job的InputSplits
   3) 必要的话,计算Job的DistributedCache的Account信息。
   4) 拷贝jar和配置文件到HDFS上。
   5) 提交Job到JobTracker,并监控其状态。

   提交Job的方式:
     为了便于Job Control,如采用系列的Map/Reduce完成一项复杂任务,需要根据Job的完成情况做出判断,有几种方式:
     RunningJob JobClient.runJob() job完成后才返回
     RunningJob JobClient.submitJob() 只提交job,然后poll RunningJob的return handle
     JobConf.setJobEndNotificationURI(String) 设置job-completion的notification,避免poll。

Hadoop API说明:建议用Configuration代替JobConf(Deprecated)。

   Map-Reduce框架自动做了下面的工作:
   1. Map-Reduce FrameWork为每个InputSplit spawn一个map任务。
   InputSplit由InputFormat生成。
   Mapper实现可以通过JobContext.getConfiguration()访问Job configuration。
   2. Framework调用setup(org.apache.hadoop.mapreduce.Mapper.Context)
   3. 然后,为InputSplit中每个key/value pair调用map(Object, Object, Context)
   4. 最后,调用cleanup(Context)

   intermedidate values根据output key分组,即Partition。
   分组后的values传递到Reducer
   在传递到Reducer之前,可以自定义Combiner

Mapper和Reducer的实现方式如下。
   实现Mapper:
   接口:public static class MapClass extends MapReduceBase 
   implements Mapper<LongWritable, Text, Text, IntWritable> {}
   MapReduceBase is Deprecated
   实现map():
   注意:map()接口在hadoop-0.20.0版中发生变化,原来接口中的OutputCollector<K2, V2>和Reporter被封装为Mapper.Context。

   实现Reducer:
   接口: public static class Reduce extends MapReduceBase
   implements Reducer<Text, IntWritable, Text, IntWritable> {}

   main函数:
   调用ToolRunner.run()
   eg: ToolRunner.run(new Configuration(), new WordCount(), args);

转自http://bbs.chinacloud.cn/archiver/showtopic-3319.aspx

posted @ 2013-11-02 17:46  wangnan45  阅读(258)  评论(0编辑  收藏  举报