Hadoop中mapred包和mapreduce包的區別


今天寫了段代碼突然發現,很多類在mapred和mapreduce中分別都有定義,下面是小菜寫的一段代碼:

public  class MyJob extends Configured implements Tool
{
    
    public static class MapClass extends MapReduceBase implements Mapper<Text, Text, Text, Text>
    {//
        public void map(Text key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException
        {
            output.collect(value, key);
        }
        
    }

    public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text>
    {

        @Override
        public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter)     throws IOException
        {
            String csv = "";
            while (values.hasNext())
            {
                csv += csv.length() > 0 ? "," : "";
                csv += values.next().toString();                
            }
            output.collect(key, new Text(csv));
        }
        
    }

    @Override
    public int run(String[] args) throws Exception
    {
        Configuration conf = getConf();
        
        JobConf  job = new JobConf(conf, MyJob.class); //JobConf job = new JobConf(conf, MyJob.class);
        
        Path in = new Path(args[0]);
        Path out = new Path(args[1]);
        FileInputFormat.setInputPaths(job, in);
        FileOutputFormat.setOutputPath(job, out);
        
        job.setJobName("MyJob");
        job.setMapperClass(MapClass.class);
        job.setReducerClass(Reduce.class);
        
        job.setInputFormat(KeyValueTextInputFormat.class);
        job.setOutputFormat(TextOutputFormat.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.set("key.value.separator.in.input.line", ",");
        
        JobClient.runJob(job);
        
        return 0;
    }
    

    public static void main(String[] args) throws Exception
    {
        // TODO Auto-generated method stub
        int res = ToolRunner.run(new Configuration(), new MyJob(), args);
        System.exit(res);
    }
}

主要看run方法:

上面代碼中的Jobconf無可厚非,只有在mapred包中有定義,這個沒問題。

但是FileInputFormat和FileOutputFormat在mapred和mapreduce中都有定義,剛開始腦海里對這些都沒有概念,就引用了mapreduce中的FileInputFormat和FIleOutputFormat。

這樣操作就帶來了后面的問題

FileInputFormat.setInputPaths(job, in);
FileOutputFormat.setOutputPath(job, out);

這兩條語句不能通過編譯,為什么呢,因為FileInputFormat.setInputPaths和 FileOutputFormat.setOutputPath的第一個參數都是Job,而不是JobConf,找了很多資料,由於對hadoop了解 少,所以找資料沒有方向感,這也是學習新東西效率低下的原因,如果有哪位大牛,知道怎么克服效率低下的問題,請不吝賜教!

后來,無意中,看到mapred包中也有這兩個類的定義,於是火箭速度修改為mapred下的包,OK,順利通過編譯!

下面還有 job.setOutputFormat(TextOutputFormat.class);語句編譯不同通過,提示參數需要擴展。。。 的參數;於是小菜也去mapred下面查找是否存在此類,正如期望,也存在此類,當即立段,修改為此包下的類,順利編譯通過,此時,頗有成就感!

可是現在小菜發現,mapred包下和mapreduce包下同時都存在又相應的類,不知道是為什么,那么下面就有目標的請教搜索引擎啦,呵呵,比剛才有很大進步。

結果令小菜很失望,就找到了一個符合理想的帖子。但是通過這個帖子,小菜知道了,mapred代表的是hadoop舊API,而mapreduce代表的是hadoop新的API。

OK,小菜在google輸入框中輸入“hadoop新舊API的區別”,結果很多。看了之后,又結合權威指南歸結如下:

1.    首先第一條,也是小菜今天碰到這些問題的原因,新舊API不兼容。所以,以前用舊API寫的hadoop程序,如果舊API不可用之后需要重寫,也就是上面我的程序需要重寫,如果舊API不能用的話,如果真不能用,這個有點兒小遺憾!

2.    新的API傾向於使用抽象類,而不是接口,使用抽象類更容易擴展。例如,我們可以向一個抽象類中添加一個方法(用默認的實現)而不用修改類之前的實現方法。因此,在新的API中,Mapper和Reducer是抽象類。

3.    新的API廣泛使用context object(上下文對象),並允許用戶代碼與MapReduce系統進行通信。例如,在新的API中,MapContext基本上充當着JobConf的OutputCollector和Reporter的角色。

4.    新的API同時支持"推"和"拉"式的迭代。在這兩個新老API中,鍵/值記錄對被推mapper中,但除此之外,新的API允許把記錄從map()方法中拉出,這也適用於reducer。分批處理記錄是應用"拉"式的一個例子。

5.    新的API統一了配置。舊的API有一個特殊的JobConf對象用於作業配置,這是一個對於Hadoop通常的Configuration對象的擴展。 在新的API中,這種區別沒有了,所以作業配置通過Configuration來完成。作業控制的執行由Job類來負責,而不是JobClient,並且 JobConf和JobClient在新的API中已經盪然無存。這就是上面提到的,為什么只有在mapred中才有Jobconf的原因。

6.   輸出文件的命名也略有不同,map的輸出命名為part-m-nnnnn,而reduce的輸出命名為part-r-nnnnn,這里nnnnn指的是從0開始的部分編號。

這樣了解了二者的區別就可以通過程序的引用包來判別新舊API編寫的程序了。小菜建議最好用新的API編寫hadoop程序,以防舊的API被拋棄!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM