1. 程式人生 > >hadoop實現文件倒排

hadoop實現文件倒排

很多類在mapred和mapreduce中分別都有定義,其中mapred是老的API 而mapreduce是新的API:
public class MyJob extends Configured implements Tool
{

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

}

public static class Reduce extends MapReduceBase implements Reducer
{

    @Override
    public void reduce(Text key, Iterator values, OutputCollector 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);
}
}

上面程式碼中的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被拋棄!!!

另外,hadoop2.7.1的web ui是在8088,和19888這兩個埠下檢視,在50070下面找不到。。