讓python在hadoop上跑起來

來源:互聯網
上載者:User
本文執行個體講解的是一般的hadoop入門程式“WordCount”,就是首先寫一個map程式用來將輸入的字串分割成單個的單詞,然後reduce這些單個的單詞,相同的單詞就對其進行計數,不同的單詞分別輸出,結果輸出每一個單詞出現的頻數。

  注意:關於資料的輸入輸出是通過sys.stdin(系統標準輸入)和sys.stdout(系統標準輸出)來控制資料的讀入與輸出。所有的指令碼執行之前都需要修改許可權,否則沒有執行許可權,例如下面的指令碼建立之前使用“chmod +x mapper.py”

1.mapper.py

#!/usr/bin/env pythonimport sysfor line in sys.stdin: # 遍曆讀入資料的每一行    line = line.strip() # 將行尾行首的空格去除  words = line.split() #按空格將句子分割成單個單詞  for word in words:    print '%s\t%s' %(word, 1)

2.reducer.py

#!/usr/bin/env pythonfrom operator import itemgetterimport syscurrent_word = None # 為當前單詞current_count = 0 # 當前單詞頻數word = Nonefor line in sys.stdin:  words = line.strip() # 去除字串首尾的空白字元  word, count = words.split('\t') # 按照定位字元分隔單詞和數量    try:    count = int(count) # 將字串類型的‘1'轉換為整型1  except ValueError:    continue  if current_word == word: # 如果當前的單詞等於讀入的單詞    current_count += count # 單詞頻數加1  else:    if current_word: # 如果當前的單詞不為空白則列印其單詞和頻數      print '%s\t%s' %(current_word, current_count)     current_count = count # 否則將讀入的單詞賦值給當前單詞,且更新頻數    current_word = wordif current_word == word:  print '%s\t%s' %(current_word, current_count)

在shell中運行以下指令碼,查看輸出結果:

echo "foo foo quux labs foo bar zoo zoo hying" | /home/wuying/mapper.py | sort -k 1,1 | /home/wuying/reducer.py# echo是將後面“foo ****”字串輸出,並利用管道符“|”將輸出資料作為mapper.py這個指令碼的輸入資料,並將mapper.py的資料輸入到reducer.py中,其中參數sort -k 1,1是將reducer的輸出內容按照第一列的第一個字母的ASCII碼值進行升序排序

其實,我覺得後面這個reducer.py處理單詞頻數有點麻煩,將單詞儲存在字典裡面,單詞作為‘key',每一個單詞出現的頻數作為'value',進而進行頻數統計感覺會更加高效一點。因此,改進指令碼如下:

mapper_1.py

但是,貌似寫著寫著用了兩個迴圈,反而效率低了。關鍵是不太明白這裡的current_word和current_count的作用,如果從字面上老看是當前存在的單詞,那麼怎麼和遍曆讀取的word和count相區別?

下面看一些指令碼的輸出結果:

我們可以看到,上面同樣的輸入資料,同樣的shell換了不同的reducer,結果後者並沒有對資料進行排序,實在是費解~

讓Python代碼在hadoop上跑起來!

一、準備輸入資料

接下來,先下載三本書:

$ mkdir -p tmp/gutenberg$ cd tmp/gutenberg$ wget http://www.gutenberg.org/ebooks/20417.txt.utf-8$ wget http://www.gutenberg.org/files/5000/5000-8.txt$ wget http://www.gutenberg.org/ebooks/4300.txt.utf-8

然後把這三本書上傳到hdfs檔案系統上:

 $ hdfs dfs -mkdir /user/${whoami}/input # 在hdfs上的該使用者目錄下建立一個輸入檔案的檔案夾 $ hdfs dfs -put /home/wuying/tmp/gutenberg/*.txt /user/${whoami}/input # 上傳文檔到hdfs上的輸入檔案夾中

尋找你的streaming的jar檔案存放地址,注意2.6的版本放到share目錄下了,可以進入hadoop安裝目錄尋找該檔案:

$ cd $HADOOP_HOME$ find ./ -name "*streaming*"

然後就會找到我們的share檔案夾中的hadoop-straming*.jar檔案:

尋找速度可能有點慢,因此你最好是根據自己的版本號碼到對應的目錄下去尋找這個streaming檔案,由於這個檔案的路徑比較長,因此我們可以將它寫入到環境變數:

$ vi ~/.bashrc # 開啟環境變數設定檔# 在裡面寫入streaming路徑export STREAM=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar

由於通過streaming介面啟動並執行指令碼太長了,因此直接建立一個shell名稱為run.sh來運行:

hadoop jar $STREAM \-files ./mapper.py,./reducer.py \-mapper ./mapper.py \-reducer ./reducer.py \-input /user/$(whoami)/input/*.txt \-output /user/$(whoami)/output

然後"source run.sh"來執行mapreduce。結果就響噹噹的出來啦。這裡特別要提醒一下:

1、一定要把本地的輸入檔案轉移到hdfs系統上面,否則無法識別你的input內容;

2、一定要有許可權,一定要在你的hdfs系統下面建立你的個人資料夾否則就會被denied,是的,就是這兩個錯誤搞得我在伺服器上面痛不欲生,四處問人的感覺真心不如自己清醒對待來的好;

3、如果你是第一次在伺服器上面玩hadoop,建議在這之前請在自己的虛擬機器或者linux系統上面配置好偽分布式然後入門hadoop來的比較不那麼頭疼,之前我並不知道我在伺服器上面營運沒有給我啟動並執行許可權,後來在自己的虛擬機器裡面運行一下example執行個體以及wordcount才找到自己的錯誤。

好啦,然後不出意外,就會complete啦,你就可以通過如下方式查看計數結果:

以上就是本文的全部內容,希望對大家學習python軟體編程有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.