我知道這個文章標題很「學術」化,很俗,讓人看起來是一篇很牛B或者很裝逼的論文!其實否則,只是一份普通的實驗報告,同時本文也不對RMM中文分 詞算法進行研究。這個實驗報告是我作高性能計算課程的實驗裏提交的。因此,下面的內容是從個人實驗報告裏摘錄出來的,看成是我學習hadoop分享出來的 一些我的經驗。python
實驗目標算法
學習編寫 Hadoop 上的 MapReduce 程序。
使用 Hadoop 分佈式計算小說《倚天屠龍記》裏的中文單詞頻率,比較張無忌身邊的兩個女人周芷若與趙敏誰在小說裏的熱度高。(爲何要提到倚天屠龍記呢?由於個人一位舍 友最近把賈靜雯演的這部戲看完了,他無時無刻不提到賈靜雯演的趙敏,因此這個實驗也取材自個人大學生活……)app
實驗原理
jsp
經過自學Hadoop的Streaming工做模式,使用Streaming可讓Hadoop運行非Java的MapReduce程序。分佈式
爲了減小咱們的實驗時間,咱們使用了以開發效率著名的Python語言來編寫咱們的mapper.py和reducer.py。其中,咱們還使用到 了一個小巧的中文分詞模塊smallseg.py,引用自(http://code.google.com/p/smallseg/,Apache License 2.0)。函數
對於中文詞庫,咱們使用搜狗實驗室提供的中文詞庫main.dic以及一個字庫suffix.dic,都可從smallseg項目中得到。oop
分佈式計算的輸入爲一個文本文件:倚天屠龍記.txt,咱們從網下下載此文本資源,而且轉換爲utf8文本編碼以方便咱們在Linux下進行分詞計算。性能
iconv -fgbk -tutf8 倚天屠龍記.txt > 倚天屠龍記utf8.txt學習
實驗環境測試
NameNode:
OS: Ubuntu11.04
CPU: Intel Core I3
Memory: 512MB
IP: 125.216.244.28
DataNode1:
OS: Ubuntu11.10
CPU: Intel Pentium 4
Memory: 512MB
IP: 125.216.244.21
DataNode2:
OS: Ubuntu11.10
CPU: Intel Pentium 4
Memory: 512MB
IP: 125.216.244.22
Mapper程序
下面是mapper.py的代碼。
#!/usr/bin/env python
from smallseg import SEG
import sys
seg = SEG()
for line in sys.stdin:
wlist = seg.cut(line.strip())
for word in wlist:
try:
print "%s\t1" % (word.encode("utf8"))
except:
pass
smallseg爲一個使用RMM字符串分割算法的中文分詞模塊。Mapper程序的過程很簡單,對每一行的中文內容進行分詞,而後把結果以單詞和頻率的格式輸出。對於全部的中文單詞,都是下面的格式,
單詞[tab]1
每一個單詞的頻率都爲1。Mapper並不統計每一行裏的單詞出現頻率,咱們把這個統計頻率的工做交給Reducer程序。
Reducer程序
下面是reducer.py的代碼.
#!/usr/bin/env python import sys current_word,current_count,word = None, 1, None for line in sys.stdin: try: line = line.rstrip() word, count = line.split("\t", 1) count = int(count) except: continue if current_word == word: current_count += count else: if current_word: print "%s\t%u" % (current_word, current_count) current_count, current_word = count, word if current_word == word: print "%s\t%u" % (current_word, current_count)
從標準輸入中讀取每個單詞頻率,而且統計。由於這些單詞已經由Hadoop爲咱們排好了順序,因此咱們只須要對一個單詞的出現次數進行累加,當出現不一樣的單詞的時候,咱們就輸出這個單詞的頻率,格式以下
單詞[tab]頻率
實驗步驟
實驗使用一個NameNode節點和兩個DataNode節點。
首先,把所須要的文件複製到每一臺主機上。這些文件都放在/home/hadoop/wc目錄下。
scp -r wc hadoop@125.216.244.21:.
scp -r wc hadoop@125.216.244.22:.
scp -r wc hadoop@125.216.244.28:.
運行Hadoop Job
本次任務,使用3個Mapper進程以及2個Reducer進程。由於分詞的步驟最爲耗時,因此咱們儘可能分配最多數目的Mapper進程。
hadoop@xiaoxia-vz:~/hadoop-0.20.203.0$ ./bin/hadoop jar contrib/streaming/hadoop-streaming-0.20.203.0.jar -mapper /home/hadoop/wc/mapper.py -reducer /home/hadoop/wc/reducer.py -input 2-in -output 2-out -jobconf mapred.map.tasks=3 -jobconf mapred.reduce.tasks=2 [...] WARN streaming.StreamJob: -jobconf option is deprecated, please use -D instead. packageJobJar: [/tmp/hadoop-unjar2897218480344074444/] [] /tmp/streamjob7946660914041373523.jar tmpDir=null [...] INFO mapred.FileInputFormat: Total input paths to process : 1 [...] INFO streaming.StreamJob: getLocalDirs(): [/tmp/mapred/local] [...] INFO streaming.StreamJob: Running job: job_201112041409_0005 [...] INFO streaming.StreamJob: To kill this job, run: [...] INFO streaming.StreamJob: /home/hadoop/hadoop-0.20.203.0/bin/../bin/hadoop job -Dmapred.job.tracker=http://125.216.244.28:9001 -kill job_201112041409_0005 [...] INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201112041409_0005 [...] INFO streaming.StreamJob: map 0% reduce 0% [...] INFO streaming.StreamJob: map 9% reduce 0% [...] INFO streaming.StreamJob: map 40% reduce 0% […] INFO streaming.StreamJob: map 67% reduce 12% [...] INFO streaming.StreamJob: map 71% reduce 22% [...] INFO streaming.StreamJob: map 100% reduce 28% [...] INFO streaming.StreamJob: map 100% reduce 100% [...] INFO streaming.StreamJob: Job complete: job_201112041409_0005 [...] INFO streaming.StreamJob: Output: 2-out
Map過程耗時:41s
Reduce過程耗時:21s
總耗時:62s
計算結果
複製計算結果到本地文件系統。
./bin/hadoop dfs -get 2-out/part* ../wc/
查看part*的部份內容:
hadoop@xiaoxia-vz:~/wc$ tail part-00000 龍的 1 龍眼 1 龍虎 2 龍被 1 龍身 2 龍鎮 1 龍骨 1 龜壽 2 龜山 1 龜裂 1 hadoop@xiaoxia-vz:~/wc$ tail part-00001 龍門 85 龍飛鳳舞 1 龍駕 1 龜 3 龜一 1 龜二 1 龜息 1 龜縮 1 龜蛇 3
下面,對輸出的結果進行合併,並按照頻率進行排序。該過程比較快,在1秒內就已經完成。
hadoop@xiaoxia-vz:~/wc$ cat part-00000 part-00001 | sort -rnk2,2 > sorted hadoop@xiaoxia-vz:~/wc$ head sorted 的 7157 張無忌 4373 是 4199 道 3465 了 3187 我 2516 他 2454 你 2318 這 1991 那 1776
咱們去掉單個字的干擾,由於咱們的實驗目的只對人名感興趣。
hadoop@xiaoxia-vz:~/wc$ cat sorted | awk '{if(length($1)>=4) print $0}' | head -n 50 張無忌 4373 說道 1584 趙敏 1227 謝遜 1173 本身 1115 甚麼 1034 張翠山 926 武功 867 一個 777 我們 767 周芷若 756 教主 739 笑道 693 明教 685 一聲 670 聽得 634 姑娘 612 師父 606 只見 590 無忌 576 少林 555 如此 547 弟子 537 之中 527 殷素素 518 楊逍 496 他們 490 不知 484 如何 466 咱們 453 兩人 453 叫道 450 二人 445 今日 443 心想 433 張三丰 425 聲道 425 義父 412 出來 402 雖然 395 滅絕師太 392 之下 389 這時 381 蓮舟 374 心中 374 即是 371 不敢 371 俞蓮 369 不能 359 身子 356
統計圖表
結論
趙敏以1227票的頻率完勝周芷若的756票,由此可知趙敏在《倚天屠龍記》裏的熱度比周芷若高。
通過本次實驗,咱們對 Hadoop 原理有了必定程度的瞭解,而且順利的完成Mapper函數和Reducer函數的設計和測試。可以運用 Hadoop 進行簡單的並行計算的實現。咱們也對並行算法和串行算法的區別和設計有了更深一層的瞭解。此外,實驗還增進了咱們的合做精神,提升了咱們的動手能力。