讓你真正明白什麼是MapReduce組合式,迭代式,鏈式

問題導讀:

能夠到這一步,說明已經對hadoop入門,並且產生問題。這個問題,似乎困惑了不少初學者。

1.比如我們輸出的mapreduce結果,需要進入下一個mapreduce,該怎麼解決?

可以使用迭代式
2.那麼什麼是迭代式?
3.什麼是依賴式?
4.什麼是鏈式?

5.三種模式各自的應用場景是什麼?



網上不少資料,但是對於新手,很難辨認,這裏給大家指出這裏面的關鍵點:

1.迭代式mapreduce
        一些複雜的任務難以用一次MapReduce處理完成,需要多次 MapReduce 才能完成任務,例如Pagrank,K-means算法都需要多次的迭代,關於 MapReduce 迭代在Mahout中運用較多。有興趣的可以參考一下Mahout的源碼。
             在MapReduce的迭代思想,類似for循環,前一個 MapReduce的輸出結果,作爲下一個 MapReduce的輸入,任務完成後中間結果都可以刪除。
        代碼示例:

  1. Configuration conf1 = new Configuration();
  2. Job job1 = new Job(conf1,"job1");
  3. .....
  4. FileInputFormat.addInputPath(job1,InputPaht1);
  5. FileOutputFromat.setOoutputPath(job1,Outpath1);
  6. job1.waitForCompletion(true);
  7. //sub Mapreduce
  8. Configuration conf2 = new Configuration();
  9. Job job2 = new Job(conf1,"job1");
  10. .....
  11. FileInputFormat.addInputPath(job2,Outpath1);
  12. FileOutputFromat.setOoutputPath(job2,Outpath2);
  13. job2.waitForCompletion(true);
  14. //sub Mapreduce
  15. Configuration conf3 = new Configuration();
  16. Job job3 = new Job(conf1,"job1");
  17. .....
  18. FileInputFormat.addInputPath(job3,Outpath2);
  19. FileOutputFromat.setOoutputPath(job3,Outpath3);
  20. job3.waitForCompletion(true);
  21. .....
複製代碼

關鍵點:
上面滿眼的代碼,下面列出關鍵代碼:
第一個job的輸出路徑爲Outpath1
FileOutputFromat.setOoutputPath(job1,Outpath1);

第二個job的輸入路徑爲Outpath1,輸出路徑爲Outpath2
FileInputFormat.addInputPath(job2,Outpath1);
FileOutputFromat.setOoutputPath(job2,Outpath2);

第三個job的輸入路徑爲Outpath2
FileInputFormat.addInputPath(job3,Outpath2);
換句話說:第一個job的輸出路徑爲第二個job的輸入路徑,以此類推。

上面採用的是一種直線式,那麼他們能不能更省事,成爲循環樣式
成爲循環式,是可以的,但是有不少需要解決的問題:這裏只是舉例,你可能還會碰到其它問題。
1.需要他們的key,value等值是完全一致的,也就是說兩個job或則說job之間必須是一致的。
2.輸入輸出路徑需要區分等。


2.依賴關係組合式MapReduce

我們可以設想一下MapReduce有3個子任務job1,job2,job3構成,其中job1和job2相互獨立,job3要在job1和job2完成之後才執行。這種關係就叫複雜數據依賴關係的組合時mapreduce。hadoop爲這種組合關係提供了一種執行和控制機制,hadoop通過job和jobControl類提供具體的編程方法。Job除了維護子任務的配置信息,還維護子任務的依賴關係,而jobControl控制整個作業流程,把所有的子任務作業加入到JobControl中,執行JobControl的run()方法即可運行程序。

下面給出僞代碼:

  1. Configuration job1conf = new Configuration();
  2. Job job1 = new Job(job1conf,"Job1");
  3. .........//job1 其他設置
  4. Configuration job2conf = new Configuration();
  5. Job job2 = new Job(job2conf,"Job2");
  6. .........//job2 其他設置
  7. Configuration job3conf = new Configuration();
  8. Job job3 = new Job(job3conf,"Job3");
  9. .........//job3 其他設置
  10. job3.addDepending(job1);//設置job3和job1的依賴關係
  11. job3.addDepending(job2);
  12. JobControl JC = new JobControl("123");
  13. JC.addJob(job1);//把三個job加入到jobcontorl中
  14. JC.addJob(job2);
  15. JC.addJob(job3);
  16. JC.run();
複製代碼

關鍵點:

下面代碼:addDepending()這個函數,作用的是建立兩個job之間的依賴關係。那麼如何建立,看下面兩行
//下面面代碼的作用是設置job3和job1的依賴關係
job3.addDepending(job1);
//下面代碼的作用是設置job3和job2的依賴關係
job3.addDepending(job2);

建立依賴關係之後,還有一步驟,也就是還有一個類需要我們瞭解JobControl,通過這個類來控制他們之間的依賴關係。如何做到,通過下面代碼:

//實例化
JobControl JC = new JobControl("123");
//把三個job加入到jobcontorl中
JC.addJob(job1);
JC.addJob(job2);
JC.addJob(job3);
JC.run();


3.鏈式MapReduce



首先看一下例子,來說明爲什麼要有鏈式MapReduce,假設在統計單詞是,會出現這樣的詞,make,made,making等,他們都屬於一個詞,在單詞累加的時候,都歸於一個詞。解決的方法爲用一個單獨的Mapreduce任務可以實現,單增加了多個Mapreduce作業,將增加整個作業處理的週期,還增加了I/O操作,因而處理效率不高。

一個較好的辦法就是在覈心的MapReduce之外,增加一個輔助的Map過程,然後將這個輔助的Map過程和核心的Mapreudce過程合併爲一個鏈式的Mapreduce,從而完成整個作業。hadoop提供了專門的鏈式ChainMapper和ChainReducer來處理鏈式任務,ChainMapper允許一個Map任務中添加多個Map的子任務,ChainReducer可以在Reducer執行之後,在加入多個Map的子任務。其調用形式如下:

  1. ChainMapper.addMapper(...);
  2.     ChainReducer.addMapper(...);
  3.     //addMapper()調用的方法形式如下:
  4.     public static void addMapper(JOb job,
  5.             Class<? extends Mapper> mclass,
  6.             Class<?> inputKeyClass,
  7.             Class<?> inputValueClass,
  8.             Class<?> outputKeyClass,
  9.             Class<?> outputValueClass,
  10.             Configuration conf
  11.     ){
  12.     }
複製代碼

其中,ChainReducer專門提供了一個setRreducer()方法來設置整個作業唯一的Reducer。

note:這些Mapper和Reducer之間傳遞的鍵和值都必須保持一致。

下面舉個例子:用ChainMapper把Map1加如並執行,然後用ChainReducer把Reduce和Map2加入到Reduce過程中。代碼如下:Map1.class 要實現map方法

  1. public void function throws IOException {
  2.         Configuration conf = new Configuration();
  3.         Job job = new Job(conf);
  4.         job.setJobName("ChianJOb");
  5.         // 在ChainMapper裏面添加Map1
  6.         Configuration map1conf = new Configuration(false);
  7.         ChainMapper.addMapper(job, Map1.class, LongWritable.class, Text.class,
  8.                 Text.class, Text.class, true, map1conf);
  9.         // 在ChainReduce中加入Reducer,Map2;
  10.         Configuration reduceConf = new Configuration(false);
  11.         ChainReducer.setReducer(job, Reduce.class, LongWritable.class,
  12.                 Text.class, Text.class, Text.class, true, map1conf);
  13.         Configuration map2Conf = new Configuration();
  14.         ChainReducer.addMapper(job, Map2.class, LongWritable.class, Text.class,
  15.                 Text.class, Text.class, true, map1conf);
  16.         job.waitForCompletion(true);
  17.     }

複製代碼

關鍵點:
鏈式,那麼什麼是鏈式,鏈式是mapreduce中存在多個map.
那麼是怎麼實現的?通過鏈式ChainMapper和ChainReducer實現。
ChainMapper允許一個Map任務中添加多個Map的子任務,ChainReducer可以在Reducer執行之後,在加入多個Map的子任務。

下面爲ChainMapper、ChainReducer:的具體實現。
ChainMapper.addMapper(job, Map1.class, LongWritable.class, Text.class,
Text.class, Text.class, true, map1conf);
ChainReducer.addMapper(job, Map2.class, LongWritable.class, Text.class,
Text.class, Text.class, true, map1conf);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章