作者:江南白衣
Hadoop 是 Google labs 的MapReduce的一個實現,Nutch項目的全部資料處理都構建在其之上。MapReduce是一種簡化的分布式編程模式,讓程式可以自動在普通機器組成的叢集中以並行方式分布執行。
就如同java程式員可以不考慮記憶體泄露一樣,MapReduce程式員也不許要關心海量資料如何被分配到多台機器上,不需要考慮機器失效的處理,不需要 考慮這些機器間如何協作共同完成工作,程式員不需要什麼並發處理或者分布式系統的經驗,就可以進行分布式的編程。
MapReduce來源於函數式編程的Map,Reduce概念,Map是映射,Reduce是規約。說了非常簡單,就真的是非常簡單的,先看 Hadoop內建的sample-WordCount ,再看Nutch裡的Indexer,Fetcher兩個實戰的例子,最後閱讀Hadoop wiki 上的HadoopMapReduce,很快就可以上手:
MapReduce過程簡記:
1.根據輸入路徑,先用FileSplit把輸入的檔案剁碎,根據InputFormat(讀入資料的格式)內含的RecordReader把資料讀入成一組(key,value)對,然後按mapper count平均分給不同的Mapper處理。(這段因為沒看過源碼,還有點模糊)
2.Mapper進行Map操作 :: (InitialKey, IntialValue) -> [(InterKey, InterValue)] 從Inupt key,value 產生中間資料集。
3.Reducer進行Reduce操作:: (Interkey, InterValuesIterator) -> [(InterKey, InterValue)],Reducer遍曆所有節點取得需要的中間資料集,再對其進行去重、過濾等後期處理,得到結果。
4.最後由OutputFormat類(輸出資料的格式)內含的RecordWriter,將最終結果輸出。結果輸出可以是檔案,也可以是其他形式,比 如Nutch的Indexer,output時並不是去寫檔案,而是調用Lucene的IndexWriter將作為中間資料集的Lucene Document存檔。
一段典型的Hadoop代碼:
public static void main(String[] args) main()
{
JobConf conf = new JobConf(WordCount. class );
conf.setJobName( " wordcount " );
jobConf.setInputFormat(MyInputFormat. class );
jobConf.setOutputFormat(MyOutputFormat. class );
jobConf.setInputKeyClass(BytesWritable. class );
jobConf.setInputValueClass(BytesWritable. class );
jobConf.setOutputKeyClass(BytesWritable. class );
jobConf.setOutputValueClass(BytesWritable. class );
jobConf.setMapperClass(MyMapper. class );
jobConf.setReducerClass(MyReducer. class );
jobConf.setNumMapTasks(num_maps);
jobConf.setNumReduceTasks(num_reduces);
JobClient.runJob(jobConf);
}
這就是一段hadoop式程式的主代碼,使用者自行實現四個內部類,MyInputFormat,MyOutputFormat,MyMapper和 MyReducer,然後一一在jobConf裡配置,最後執行runJob()即可。對比一下Nutch的源碼就知道,只要把原來一段順序執行的代碼, 拆分到上面四個類裡面去,再在jobConf裡進行指定,就可以擁有分布式執行的能力,無須要處理分布式編程的代碼。配置一下伺服器列表,在每台伺服器上 執行nutch/bin/start-all.sh,你的代碼就分布式地執行了。
最後看一下Hadoop的結構,除了MapReduce的分發外,還有兩個很重要的部分:
Hadoop的快速介面反射式RPC系統:IPC。
Hadoop的Distributed File SystemNDFS:見 CSharpProgrammer blog上的文章。
注1:筆記中部分句子直接從網上文章摘錄,不一一聲明。
注2:Hadoop 目前版本為0.5,還不夠成熟,看過源碼的Donald對其源碼評價一般,值得繼續等待。