Hadoop 新旧API之间区别

版权声明:本文为博主原创文章,转载请标明出处: https://blog.csdn.net/u012343297/article/details/80191077

从0.20.0 版本开始,Hadoop 同时提供了新旧两套MapReduce API。部分早期的0.20发行版本反对使用旧的api,但是后续版本中可以继续使用旧的api,因此1.x和2.x发行版本同时支持就的api。

新旧API之间有如下几个明显区别:

  • 新API倾向使用虚类,而不是接口,因为更有利扩展。
  • 新API移到org.apache.hadoop.mapreduce包及其子包中,而旧的API放在org.apache.hadoop.mapred下。
  • 新API充分使用上下文对象,使用户代码能在MapReduce系统通信。例如,新的Context基本统一了旧的API中的JobConf、OutputCollector和Reporter的功能。
  • 键/值对记录在这两类API中都被推给了mapper和reducer,但除此之外,新的API通过重写run()方法允许mapper和reducer控制执行流程。
  • 新API中作业控制由Job类实现,而旧的API中的JobClient类,新的API中删除了JobClient类。
  • 新增的API实现了配置的统一。旧API通过一个特殊的JobConf对象配置作业,该对象是Hadoop配置对象的一个扩展。在新API中,作业的配置由Configuration类完成。
  • 输出文件的命名方式稍有不同。在旧的API中map和reduce的输出被统一命名为part-nnmm,但是新的API中map的输出文件名为part-m-nnnn,而reduce的输出文件名为part-r-nnnnn(其中nnnnn是从0开始的表示分块序号的整数)。
  • 新的API中用户冲在函数被声明为抛出异常java.lang.InterruputedException。这意味着可以用代码来实现中断响应,从而使该框架在必要时可以优雅的取消长时间运行的作业。
  • 在新的API中,reduce()传递的值是java.lang.Iterable类型的,而非java.lang.Iterator类型,这一改变使我们可以更容易是欧诺更for-each循环来迭代这些值。
----------------Iterator迭代 ----------------------
public static class Reduce extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable>{

        @Override
        public void reduce(Text key, Iterator<LongWritable> values, OutputCollector<Text, LongWritable> output,
                Reporter reporter) throws IOException {
            long count = 0;

            while(values.hasNext()){
                count+=values.next().get();
            }
            output.collect(key, new LongWritable(count));
        }

    }
--------------Iterable for-each迭代---------------
public static class FriendListReducer extends Reducer<Text,Text,Text,Text>{
        private Text friendsNames=new Text();
        @Override
        protected void reduce(Text key,
                Iterable<Text> values,Context context) throws IOException, InterruptedException{
            StringBuffer buffer=new StringBuffer();
            for(Text name:values){
                buffer.append(","+name);
            }
            friendsNames.set(buffer.toString());
            context.write(key,friendsNames);
        }
    }
展开阅读全文

关于hadoop新旧api的问题

12-09

各位大虾,有个问题不知道你们遇到没有,或者遇到后怎么解决的。rnhadoop在0.20.2后采用了新版的api,基本的区别大家都知道,但是问题是有些旧版api他没有开放出来的。举个具体的例子吧,rn比如我们要测试作业组合依赖式工作,这样就需要用到JobControl类,但是这个类是在org.apache.hadoop.mapred.jobcontrol这个包里,而这样的话,基本上就不能在调用新api的方法了,比如其中的一个方法addJobs(Collection jobs) 中的Job必须是org.apache.hadoop.mapred下的job而不能用org.apache.hadoop.mapreduce 包里面的job了,可是我们前面写的代码都是用org.apache.hadoop.mapreduce的类啊?这个问题在之前的地方也遇到过。当然有个解决办法,就是都用旧版的API,貌似可以解决,那这样的话还弄个新版的api干什么呢?rn源码如下:rnpackage multijob.dependencejob;rnrn/**rn * 此源码用于演示顺序组合式MapReduce作业的执行、rn * 这里我们把x,y,z任务的依赖表示为,z依赖于x,yrn * 但是问题是其依赖的控件JobControl是旧版本的API,而我们建立的任务是新版本的job,会报类型不匹配的错误rn * 如果我们改成就版本的job,那么其要求的map和reduce类也是就旧版本的了,这显然不对啊。rn * 如何解决这个版本问题呢?rn * 后面的链式处理中也出现了这个问题?这是个共性问题。rn */rnimport java.io.IOException;rnimport java.util.Iterator;rnrnimport org.apache.hadoop.conf.Configuration;rnimport org.apache.hadoop.fs.Path;rnimport org.apache.hadoop.io.LongWritable;rnimport org.apache.hadoop.io.Text;rnimport org.apache.hadoop.mapred.JobConf;rnimport org.apache.hadoop.mapred.jobcontrol.JobControl;rnimport org.apache.hadoop.mapreduce.Job;rnimport org.apache.hadoop.mapreduce.Mapper;rnimport org.apache.hadoop.mapreduce.Reducer;rnimport org.apache.hadoop.mapreduce.lib.input.FileInputFormat;rnimport org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;rnimport org.apache.hadoop.util.GenericOptionsParser;rnrnpublic class MainJob rnrn public static class MainMap extendsrn Mapper rn public void map(LongWritable key, Text value, Context context)rn throws IOException, InterruptedException rn context.write(key, value);rn rn rnrn public static class MainReduce extendsrn Reducer rnrn public void reduce(LongWritable key, Iterator values,rn Context context) throws IOException, InterruptedException rnrn /**rn * nothingrn */rn context.write(new Text("2"), new Text("2"));rnrn rn rnrn public static void main(String[] args) throws Exception rn /*rn * job2参数设置rn */rn Configuration jobXConf = new Configuration();rnrn String[] ioArgs = new String[] "testin/stjoin.txt", "output/link8" ;rn String[] otherArgs = new GenericOptionsParser(jobXConf, ioArgs)rn .getRemainingArgs();rn if (otherArgs.length != 2) rn System.err.println("Usage: wordcount ");rn System.exit(2);rn rn Job jobX = new Job(jobXConf,"JobX");rn jobX.setJarByClass(JobX.class);rnrn jobX.setMapperClass(JobX.MapX.class);rn jobX.setReducerClass(JobX.ReduceX.class);rnrn // job1.setOutputKeyClass(Text.class);rn // job1.setOutputValueClass(Text.class);rnrn FileInputFormat.addInputPath(jobX, new Path(otherArgs[0]));rn FileOutputFormat.setOutputPath(jobX, new Path(otherArgs[1]));rnrn // 等待第一个job完成以后在再执行第二个任务rn // jobX.waitForCompletion(true);rnrn /*rn * jobY参数设置rn */rn Configuration jobYConf = new Configuration();rn String[] ioArgsY = new String[] "output/link8", "output/linkend8" ;rn String[] otherArgsY = new GenericOptionsParser(jobYConf, ioArgsY)rn .getRemainingArgs();rn if (otherArgsY.length != 2) rn System.err.println("Usage: wordcount ");rn System.exit(2);rn rn Job jobY = new Job(jobYConf, "JobY");rn jobY.setJarByClass(JobY.class);rnrn jobY.setMapperClass(JobY.MapY.class);rn jobY.setReducerClass(JobY.ReduceY.class);rnrn // job2.setOutputKeyClass(Text.class);rn // job2.setOutputValueClass(Text.class);rnrn // job2.setInputFormatClass(KeyValueTextInputFormat.class);rn rn FileInputFormat.addInputPath(jobY, new Path(otherArgsY[0]));rn FileOutputFormat.setOutputPath(jobY, new Path(otherArgsY[1]));rnrn // jobY.waitForCompletion(true);rnrn /*rn * jobMain参数设置rn */rn Configuration jobMConf = new Configuration();rn String[] ioArgsM = new String[] "output/link8", "output/linkend8" ;rn String[] otherArgsM = new GenericOptionsParser(jobMConf, ioArgsY)rn .getRemainingArgs();rn if (otherArgsM.length != 2) rn System.err.println("Usage: wordcount ");rn System.exit(2);rn rn Job jobM = new Job(jobMConf, "JobM");rn jobM.setJarByClass(MainJob.class);rnrn jobM.setMapperClass(MainJob.MainMap.class);rn jobM.setReducerClass(MainJob.MainReduce.class);rnrn // job2.setOutputKeyClass(Text.class);rn // job2.setOutputValueClass(Text.class);rnrn // job2.setInputFormatClass(KeyValueTextInputFormat.class);rn rn FileInputFormat.addInputPath(jobM, new Path(otherArgsM[0]));rn FileOutputFormat.setOutputPath(jobM, new Path(otherArgsM[1]));rnrn // 设置任务job之间的依赖关系rnrn // 设置任务运行模组rn JobControl jc = new JobControl("compound");rn /**这里会报错,显示类型不匹配**也就是说我们设置的jobx是mapreduce包下的,而其要求的是mapred下面*/rn jc.addJob(jobX);rn jc.addJob(jobY);rn jc.addJob(jobM);rn jc.run();rnrn rnrnrnrn问题总结:rn为什么旧版API包下的方法不能访问新版API包下的方法?而且部分旧版API包下的方法并没有开放出来,如何解决呢? 论坛

没有更多推荐了,返回首页