MapReduce 2.0程式設計實踐(涉及多語言程式設計)
Hadoop提供了三種程式設計方式:Java(最原始的方式、Hadoop Streaming(支援多語言)以及Hadoop Pipes(支援C/C++)。Java程式設計介面是所有程式設計方式的基礎。不同的程式設計介面只是暴露給使用者的形式不同而已,內部執行引擎是一樣的。不同程式設計方式效率不同。
與Linux管道機制一致,通過標準輸入輸出實現程序間通訊 。 幾個舉例:
cat 1.txt | grep “dong” | sort
cat 1.txt | python grep.py | java sort.jar
JAVA程式設計
Map階段將輸入的行資料,解析成單詞-1的key-value對。其虛擬碼如右圖所示。
Reduce階段將map階段的輸出結果進行歸併,最後統計輸出。
MapReduce的資料流如圖所示。inputfotmat中的RecordReader函式將split的每一行解析成偏移量-行資料的key-value形式。map實現單詞切分。reduce實現歸併。最終,統計文字中的單詞數。
Grep問題
一批TB或者PB量級的文件,需要完成以下功能: 搜尋符合某種規則(正則表示式)的單詞或者句子。然後,統計相應的單詞或者句子的數目。最後,按照數目對其進行排序,並輸出最終結果。
該過程執行流程如上圖所示。分兩個過程執行,word統計和sort排序。貼出實現過程如下:
多語言程式設計
以標準輸入流作為輸入。例如:C++:cin 、C:scanf 。以標準輸出流作為輸出。例如:C++:cout 、C:printf 可實現Mapper和Reducer,其他元件( InputFormat、Partitioner等需要用Java語言實現)。用C++實現wordcount如下圖所示:
map階段
reduce階段
執行c++mapreduce: 編譯程式,生成可執行檔案; g++ -o mapper mapper.cpp ;g++ -o reducer reducer.cpp。 測試程式; cat test.txt | ./mapper | sort | ./reducer
Streaming程式執行方式
區分通用引數和命令列引數,通用引數應放在命令列引數前面,否則不起作用。通用引數有7個: -conf -D -fs -jt -files - libjars -archives 。“-file”或者“-files”引數,設定要分發到各個節點上的檔案,對於mapper和reducer檔案,必須要用或者“-files” 或“-file”指定。 如: -files mapper,reducer 和-file mapper -file reducer 。每次執行程式前,需要清空輸出目錄bin/hadoop
fs -rmr /test/output 。
下面用PHP實現wordcount:
map階段:
reduce階段:
測試mapper和reducer:
cat test.txt| php mapper.php | sort | php reducer.php
在Hadoop上執行 :
最後,Java程式設計是Hadoop最原始開發語言。支援所有功能,是其他程式設計方式的基礎。 Streaming程式設計僅用於開發Mapper和Reducer,其他元件需採用 Java實現。其天生支援文字格式,但二進位制格式支援較弱。通常用於簡單的文字資料處理,加快開發效率。