原則上,Hadoop是可以支援幾乎任何語言的。
原文連結:http://rdc.taobao.com/team/top/tag/hadoop-php-stdin/
用PHP寫hadoop的mapreduce程式
Posted by 覃 健祥 on 03月 28th, 2011
Hadoop本身是Java寫的,所以,給hadoop寫mapreduce,人們會自然地想到java
但hadoop裡面有個contrib叫做hadoop streaming,這是一個小工具,為hadoop提供streaming支援,使得任何支援標準IO
(stdin, stdout)的可執行程式都能成為hadoop的mapper或者reducer
例如:hadoop jar hadoop-streaming.jar -input SOME_INPUT_DIR_OR_FILE -output SOME_OUTPUT_DIR -mapper /bin/cat -reducer /usr/bin/wc
在這個例子裡,就使用了Unix/Linux內建的cat和wc工具來作為mapper / reducer,是不是很神奇?
如果你習慣了使用一些動態語言,用動態語言來寫mapreduce吧,跟之前的編程沒有任何不同,hadoop只是運行它的一個架構,下面我示範一下用PHP來實現Word
Counter的mapreduce。
找到streaming jar
hadoop根目錄下是沒有hadoop-streaming.jar的,因為streaming是一個contrib,所以要去contrib下面找,以hadoop-0.20.2為例,它在這裡:
$HADOOP_HOME/contrib/streaming/hadoop-0.20.2-streaming.jar
寫mapper
建立一個wc_mapper.php,寫入如下代碼:
#!/usr/bin/php<?php $in = fopen(“php://stdin”, “r”); $results = array(); while ( $line = fgets($in, 4096) ){ $words = preg_split(‘/\W/’, $line, 0, PREG_SPLIT_NO_EMPTY); foreach ($words as $word) $results[] = $word; } fclose($in); foreach ($results as $key => $value){ print “$value\t1\n”; }
這段代碼的大致意思是:把輸入的每行文本中的單詞找出來,並以”
hello 1
world 1″
這樣的形式輸出出來。
和之前寫的PHP基本沒有什麼不同,對吧,可能稍微讓你感到陌生有兩個地方:
PHP作為可執行程式
第一行的“#!/usr/bin/php”告訴linux,要用/usr/bin/php這個程式作為以下代碼的解譯器。寫過linux shell的人應該很熟悉這種寫法了,每個shell指令碼的第一行都是這樣: #!/bin/bash, #!/usr/bin/python
有了這一行,儲存好這個檔案以後,就可以像這樣直接把wc_mapper.php當作cat, grep一樣的命令執行了:./wc_mapper.php
使用stdin接收輸入
PHP支援多種參數傳入的方法,大家最熟悉的應該是從$_GET, $_POST超全域變數裡面取通過Web傳遞的參數,次之是從$_SERVER['argv']裡取通過命令列傳入的參數,這裡,採用的是標準輸入stdin
它的使用效果是:
在linux控制台輸入 ./wc_mapper.php
wc_mapper.php運行,控制台進入等候使用者鍵盤輸入狀態
使用者通過鍵盤輸入文本
使用者按下Ctrl + D終止輸入,wc_mapper.php開始執行真正的商務邏輯,並將執行結果輸出
那麼stdout在哪呢?print本身已經就是stdout啦,跟我們以前寫web程式和CLI指令碼沒有任何不同。
寫reducer
建立一個wc_reducer.php,寫入如下代碼:
#!/usr/bin/php<?php $in = fopen(“php://stdin”, “r”); $results = array(); while ( $line = fgets($in, 4096) ){ list($key, $value) = preg_split(“/\t/”, trim($line), 2); $results[$key] += $value; } fclose($in); ksort($results); foreach ($results as $key => $value){ print “$key\t$value\n”; }
這段代碼的大意是統計每個單詞出現了多少次,並以”
hello 2
world 1″
這樣的形式輸出
用hadoop來運行上傳要統計的樣本文本
hadoop fs -put *.TXT /tmp/input
以Streaming方式執行PHP mapreduce程式
hadoop jar hadoop-0.20.2-streaming.jar -input /tmp/input -output /tmp/output -mapper wc_mapper.php的絕對路徑 -reducer wc_reducer.php的絕對路徑
注意:
input和output目錄是在hdfs上的路徑
mapper和reducer是在本地機器的路徑,一定要寫絕對路徑,不要寫相對路徑,以免到時候hadoop報錯說找不到mapreduce程式
查看結果
hadoop fs -cat /tmp/output/part-00000