官术网_书友最值得收藏!

5.3 案例分析:單詞計數

假如有這樣一個例子,需要統計過去10年計算機論文中出現次數最多的幾個單詞,以分析當前的熱點研究議題是什么。

這一經典的單詞計數案例可以采用MapReduce處理。MapReduce中已經自帶了一個單詞計數程序WordCount,如同Java中的經典程序“Hello World”一樣,WordCount是MapReduce中統計單詞出現次數的Java類,是MapReduce的入門程序。

例如,輸入內容如下的文件,要求計算出文件中單詞的出現次數,且按照單詞的字母順序進行排序,每個單詞和其出現次數占一行,單詞與出現次數之間有間隔:

直接運行MapReduce自帶的WordCount程序對上述文件內容進行計算即可,其計算結果如下:

下面進一步對WordCount程序進行分析。

1. 設計思路

WordCount對于單詞計數問題的解決方案為:先將文件內容切分成單詞,然后將所有相同的單詞聚集到一起,最后計算各個單詞出現的次數,將計算結果排序輸出。

根據MapReduce的工作原理可知,Map任務負責將輸入數據切分成單詞;Shuffle階段負責根據單詞進行分組,將相同的單詞發送給同一個Reduce任務;Reduce任務負責計算單詞出現次數并輸出最終結果。

由于MapReduce中傳遞的數據都是<key,value>對形式的,而且Shuffle的排序、聚集和分發也是按照<key,value>對進行的,因此可將map()方法的輸出結果設置為以單詞作為key,1作為value的形式,表示某單詞出現了1次(輸入map()方法的數據則采用Hadoop默認的輸入格式,即文件每一行的起始位置作為key,本行的文本內容作為value)。由于reduce()方法的輸入是map()方法的輸出聚集后的結果,因此格式為<key, value-list>,也就是<word, {1,1,1,1,…}>;reduce()方法的輸出則可設置成與map()方法輸出相同的形式,只是后面的數值不再是固定的1,而是具體計算出的某單詞所對應的次數。

WordCount程序的執行流程如圖5-5所示。

圖5-5 MapReduce單詞計數執行流程

2. 程序源碼

WordCount程序類的源代碼如下:

3. 程序解讀

Hadoop本身提供了一整套可序列化傳輸的基本數據類型,而不是直接使用Java的內嵌類型。Hadoop的IntWritable類型相當于Java的Integer類型,LongWritable相當于Java的Long類型,TextWritable相當于Java的String類型。

TokenizerMapper是自定義的內部類,繼承了MapReduce提供的Mapper類,并重寫了其中的map()方法。Mapper類是一個泛型類,它有4個形參類型,分別指定map()方法的輸入key、輸入value、輸出key、輸出value的類型。本例中,輸入key是一個長整數偏移量,輸入value是一整行單詞,輸出key是單個單詞,輸出value是單詞數量。Mapper類的核心源碼如下:

同樣,IntSumReducer是自定義的內部類,繼承了MapReduce提供的Reducer類,并重寫了其中的reduce()方法。Reducer類跟Mapper類一樣,是一個泛型類,有4個形參類型,分別指定reduce()方法的輸入key、輸入value、輸出key、輸出value的類型。Reducer類的輸入參數類型必須匹配Mapper類的輸出類型,即Text類型和IntWritable類型。

本例中,reduce()方法的輸入參數是單個單詞和單詞數量的集合,即<word, {1,1,1,1,…}>。reduce()方法的輸出也必須與Reducer類規定的輸出類型相匹配。Reducer類的核心源碼如下:

main()方法中的Configuration類用于讀取Hadoop的配置文件,例如core-site.xml、mapred-site.xml、hdfs-site.xml等。也可以使用set()方法重新設置相關配置屬性,例如重新設置HDFS的訪問路徑而不使用配置文件中的配置,代碼如下:

main()方法中的job.setCombinerClass(IntSumReducer.class);指定了Map任務規約的類。這里的規約的含義是,將Map任務的結果進行一次本地的reduce()操作,從而減輕遠程Reduce任務的壓力。例如,把兩個相同的“hello”單詞進行規約,由此輸入給reduce()的就變成了<hello,2>。實際生產環境是由多臺主機一起運行MapReduce程序的,如果加入規約操作,每一臺主機會在執行Reduce任務之前進行一次對本機數據的規約,然后再通過集群進行Reduce任務操作,這樣就會大大節省Reduce任務的執行時間,從而加快MapReduce的處理速度。本例的Map任務規約類使用了自定義Reducer類IntSumReducer,需要注意的是,并不是所有的規約類都可以使用自定義Reducer類,需要根據實際業務使用合適的規約類,也可以自定義規約類。

4. 程序運行

下面以統計文本文件中的單詞頻數為例,講解如何運行上述單詞計數程序WordCount,操作步驟如下:

 執行以下命令,在HDFS根目錄下創建文件夾input:

在本地新建一個文本文件words.txt,向其寫入以下單詞內容:

執行以下命令,將words.txt上傳到HDFS的/input目錄中:

 進入Hadoop安裝目錄,執行以下命令,運行Hadoop自帶的WordCount程序:

上述命令中的/input為數據來源目錄,/output為結果數據存儲目錄。

需要注意的是,HDFS中不應存在目錄/output,程序會自動創建,若存在則會拋出異常。

若控制臺輸出以下信息,表示程序運行正常:

程序運行過程中也可以訪問YARN ResourceManager的Web界面http://centos01:8088查看程序的運行狀態,如圖5-6所示。

圖5-6 YARN ResourceManager Web界面

 程序運行的結果以文件的形式存放在HDFS的/output目錄中,執行以下命令,查看目錄/output中的內容:

可以看到,/output目錄中生成了兩個文件:_SUCCESS和part-r-00000,_SUCCESS為執行狀態文件,part-r-00000則存儲實際的執行結果,如圖5-7所示。

圖5-7 查看結果文件

可以執行以下命令,將運行結果下載到本地查看:

也可以執行以下命令,直接查看結果文件中的數據,如圖5-8所示。

圖5-8 查看單詞計數結果數據

主站蜘蛛池模板: 伽师县| 神农架林区| 正镶白旗| 垫江县| 商洛市| 鹤庆县| 黄平县| 界首市| 鄂温| 屯昌县| 黄骅市| 洛阳市| 松桃| 遂昌县| 开阳县| 安图县| 通道| 新建县| 长武县| 文化| 南漳县| 台南市| 平定县| 石家庄市| 繁昌县| 驻马店市| 舟曲县| 中方县| 安陆市| 衡东县| 松江区| 开封市| 白玉县| 湖北省| 正镶白旗| 德令哈市| 类乌齐县| 武功县| 江门市| 庆安县| 三河市|