Hadoop Streaming的基本原理與參數解析

Hadoop Streaming原理介紹

在這裏插入圖片描述
Hadoop是基於hdfs和MapReduce的分佈式框架。由於hadoop是基於java語言的,對於其他語言實現map reduce操作不太方便,因此出現了hadoop streaming。

hadoop streaming可以將各種非java語言的腳本(script)或者可執行文件(executable)作爲map和reduce函數(當然java的更可以)。其基本的方法就是將輸入和輸出都通過標準輸入輸出流來進行。這樣,我們就可以從標準輸入讀取數據,進行map操作,傳給reduce,再進行合併,輸出到標準輸出。我們發現,這個過程中,並沒有提到具體的語言,因爲都是在標準的I / O stream中操作的。

可執行文件可以是python的一個.py腳本,也可以是一個自定義的.sh的shell腳本。或者直接用linux自帶的函數,如 cat, wc 等。

標準輸入輸出,在shell腳本中,可以用cat 等方式,而輸出則可以用 > 或者管道符號 | 。在c中就是stdio,c++裏是cin和cout。python中就是sys.stdin和print。等等。只要從標準輸入拿數據,並且寫到標準輸出中,hadoop streaming都能正確地運行。

hadoop streaming的基本原理示意圖如下:

在這裏插入圖片描述
可以看到,輸入首先在hdfs上進行split,然後分別用mapper處理,然後經過shuffle&sort,進入reducer,匯合,得到最終結果。可以看到,這裏深顏色的mapper和reducer就是我們的可執行文件或者腳本。而從streaming java mapper/reducer可以看出,實際上是hadoop streaming對自定義的mapper和reducer進行了一個java的封裝,在封裝的mapper和reducer內部,輸出輸出是用stdin和stdout傳的,消除了不同語言腳本的差異。相當於開了一個java 的MapReduce,然後再運行自定義腳本,並將輸入的k-v對轉成用stdin,通過管道餵給自定義腳本,得到輸出後,通過stdout傳出來,再重新整理成k-v對。

下面我們看看實際中的hadoop streaming是如何使用的。

Hadoop Streaming的用法和參數簡介

hadoop streaming的基本形式如下所示:

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper /bin/cat \
    -reducer /bin/wc

首先是hadoop的二進制文件路徑,然後jar,運行hadoop-streaming.jar這個jar包,後面跟着一些參數。輸入輸出的存放位置,以及mapper和reducer的可執行文件。在上面,我們的mapper就是linux 中的cat函數,而reducer則是wc函數。因此這個腳本的作用就是,將所有輸入cat起來,然後統計一下字數。

下面我們來看下hadoop streaming的各種參數:

bin/hadoop command [genericOptions] [streamingOptions]

這裏,通用option在前面,streaming的在後面。所謂通用的option指的是如下這些參數,即在hadoop中本身也存在的參數:
在這裏插入圖片描述
比如,-conf指定配置文件,在直接用hadoop操作是也可以這樣使用。同理,-D表示和directory相關的一些參數,它的形式比如:

   -D mapred.local.dir=/tmp/local
   -D mapred.system.dir=/tmp/system
   -D mapred.temp.dir=/tmp/temp

-D的參數常用的有以下幾個:

-D mapred.job.name 就是給提交到hdfs的job起個名字
-D mapred.job.priority job的優先級,有五種取值:LOW、VERY_LOW、NORMAL、HIGH、VERY_HIGH 
-D mapred.job.map.capacity 最多同時運行map數量
-D mapred.job.reduce.capacity 最多同時運行reduce數量
-D mapred.map.tasks map任務數
-D mapred.reduce.tasks reduce任務數

而streaming options就是hadoop streaming特有的一些參數,主要包括以下幾個:

-input : 輸入文件路徑,是hdfs集羣上的路徑
-output : 輸出路徑,也是集羣的
-mapper : mapper腳本名,或者可執行文件名稱,比如 "cat"/"mypyscript.py"-reducer : reduer腳本或可執行文件名,如"cat"或者py文件名等
-file : 隨job提交的文件路徑,這裏是本地路徑

在執行hadoop streaming時,mapper和reducer腳本不一定都在集羣上,當集羣上沒有對應的mapper和reducer時,需要通過-file,把所需要的所有文件都提交上來(和job一起)。比如,在執行mapper的時候,需要用到腳本my.py,以及一個字典 mydict.dict,那麼,可以這麼寫:

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper my.py \
    -reducer cat \
    -file my.py \
    -file mydict.dict

這裏補充一點,在普通場景下,我們的程序較爲複雜,體量較大,而數據則很方便可以下載到本地,這種情況下,我們的程序不動,而數據需要被下載過來。而在大數據場景下,數據體量非常之大,而我們的程序的操作則比較簡單,因此,採用了相反的策略,即數據不動,將腳本傳過去找數據,然後在hdfs上運算。

我只能期待着,
那一天——
地下的烈火衝騰,
把這活棺材和我一齊燒掉,
我應該在烈火和熱血中
得到永生。
—— 葉挺 《囚歌》

2019年11月5日00:17:13

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章