一、境遇
成都創(chuàng)新互聯(lián)是一家集網站建設,峨眉山企業(yè)網站建設,峨眉山品牌網站建設,網站定制,峨眉山網站建設報價,網絡營銷,網絡優(yōu)化,峨眉山網站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網站。
接觸Hadoop已經有半年了,從Hadoop集群搭建到Hive、HBase、Sqoop相關組件的安裝,甚至Spark on Hive、Phoenix、Kylin這些邊緣的項目都有涉及。如果說部署,我自認為可以沒有任何問題,但是如果說我對于這個系統(tǒng)已經掌握了,我卻不敢這么講,因為至少MapReduce我還沒有熟悉,其工作機制也只是一知半解。關于MapReduce的運算,我差不多理解了,但是實際實現(xiàn)現(xiàn)在卻只能靠找到的代碼,真的是慚愧的很。
于是再也忍不住,一定要有點自己的東西,最起碼,寫的時候不用去找別人的博客,嗯,找自己的就行。
二、實驗
1、實驗過程
最開始實驗的是最簡單的去重MapReduce,在本地文件實驗時沒有任何問題,但把文件放到HDFS上就怎么也找不到了,究其原因,HDFS上的需要用Hadoop執(zhí)行jar文件才可以
1)javac輸出類到指定目錄 dir
javac *.java -d dir
2)jar打包class文件
1,打包指定class文件到target.jar
jar cvf target.jar x1.class x2.class ... xn.class
2,打包指定路徑dir下的所有class文件到target.jar
jar cvf target.jar -C dir .
3,打包class文件成可執(zhí)行jar,程序入口Main函數(shù)
jar cvfe tarrget.jar Main -C dir .
Hadoop只需要普通jar即可,不用打包成可執(zhí)行jar
3)執(zhí)行jar,主類MapDuplicate
Hadoop jar target.jar MapDuplicate (params)
2、代碼分析
1)import類
import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser;
Configuration類:用來設定Hadoop的參數(shù),如:IP、端口等
Path:用來設定輸入輸出路徑
IntWritable:MapReduce用到的int類型
Text:MapReduce用到的string類型
Job:生成MapReduce任務的主類,任務參數(shù)也在此類中設定
Mapper:被繼承的Map類
Reducer:被繼承的Reduce類
FileInputFormat:輸入文件格式
FileOutputFormat:輸出文件格式(可改為其它IO類,如數(shù)據(jù)庫)
GenericOptionsParser:解析命令行參數(shù)的類
2)代碼結構
public class MapDuplicate { public static class Map extends Mapper<...> { ... } public static class Reduce extends Reducer<...> { ... } public static void main(String[] args) throws Ex { ... } }
2)Map類
public static class Map extends Mapper
Map類的主要作用是將數(shù)據(jù)進行統(tǒng)一處理,按照規(guī)則給出鍵值對,為Combine和Reduce等Reduce操作提供標準化數(shù)據(jù)。從代碼上來講,均繼承Mapper類,并實現(xiàn)map函數(shù)
Mapper類繼承的四個參數(shù),前兩個分別是輸入數(shù)據(jù)鍵和值的類型,一般寫Object,Text即可;后兩個是輸出數(shù)據(jù)鍵和值的類型,這兩個類型必須和Reduce的輸入數(shù)據(jù)鍵值類型一致。
所有的Java值類型在送到MapReduce任務前都要轉化成對應的值類型:如:String->Text,int->IntWritable,long->LongWritable
Context是Java類與MapReduce任務交互的類,它把Map的鍵值對傳給Combiner或者Reducer,也把Reducer的結果寫到HDFS上
3)Reduce類
public static class Reduce extends Reducer{ public void reduce(Text key,Iterable values,Context context) throws IOException,InterruptedException { context.write(key,new Text("")); } }
Reduce有兩種操作,Combine和Reduce,都繼承Reducer類。前者用于對數(shù)據(jù)進行預處理,將處理好的數(shù)據(jù)交給Reduce,可以看成是本地的Reduce,當不需要任何處理時,Combine可以直接用Reduce代替;后者用于對數(shù)據(jù)進行正式處理,將相同鍵值的數(shù)據(jù)合并,每一個Reduce函數(shù)過程只處理同一個鍵(key)的數(shù)據(jù)。
Reducer類繼承的四個參數(shù),前兩個是輸入數(shù)據(jù)鍵和值的類型,必須與Mapper類的輸出類型一致(Combine也必須一致,而且Combine輸出需要跟Reduce的輸入一致,所以Combine輸入輸出類型必須是相同的);后兩個是輸出數(shù)據(jù)鍵和值的類型,即我們最終得到的結果
4)Main函數(shù)
public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("mapred.job.tracker","XHadoop1:9010"); String[] ioArgs = new String[] {"duplicate_in","duplicate_out"}; String[] otherArgs = new GenericOptionsParser(conf,ioArgs).getRemainingArgs(); if (otherArgs.length != 2) { System.err.println("Usage: MapDuplicate"); System.exit(2); } Job job = new Job(conf,"MapDuplicate"); job.setJarByClass(MapDuplicate.class); job.setMapperClass(Map.class); job.setCombinerClass(Reduce.class); job.setReducerClass(Reduce.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); FileInputFormat.addInputPath(job,new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job,new Path(otherArgs[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); }
首先,必須有Configuration類,通過這個類指定工作的機器
然后,接收參數(shù)的語句,這個不解釋了
然后,需要有Job類,指定MapReduce處理用到的類,需要指定的有:Mapper類、Combiner類、Reducer類、輸出數(shù)據(jù)鍵和值類型的類
然后,指定輸入數(shù)據(jù)的路徑
然后,等待任務結束并退出
三、總結
這個實驗可以說是最簡單的MapReduce,但是麻雀雖小五臟俱全。
從原理來講,MapReduce有以下步驟:
HDFS(Block)->Split->Mapper->Partion->Spill->Sort->Combiner->Merge->Reducer->HDFS
1、HDFS輸入數(shù)據(jù)被分成Split,被Mapper類讀取,
2、Mapper讀取數(shù)據(jù)后,將任務進行Partion(分配)
3、如果Map操作內存溢出,需要Spill(溢寫)到磁盤上
4、Mapper進行Sort(排序)操作
5、排序之后進行Combine(合并key)操作,可以理解為本地模式Reduce
6、Combine的同時會進行溢出文件的Merge(合并)
7、所有任務完成后將數(shù)據(jù)交給Reducer進行處理,處理完成寫入HDFS
8、從Map任務開始到Reduce任務開始的數(shù)據(jù)傳輸操作叫做Shuffle
從編程來講,MapReduce有以下步驟:
1、編寫Mapper類
2、編寫Combiner類(可選)
3、編寫Reducer類
4、調用過程:參數(shù)配置Configuration
指定任務類
指定輸入輸出格式
指定數(shù)據(jù)位置
開始任務
以上僅僅是淺層認識,僅供學習參考及備查。