用PHP編寫Hadoop的MapReduce程序

Hadoop流

雖然Hadoop是用java寫的,但是Hadoop提供了Hadoop流,Hadoop流提供一個API, 允許用戶使用任何語言編寫map函數和reduce函數.
Hadoop流動關鍵是,它使用UNIX標準流作為程序與Hadoop之間的接口。因此,任何程序只要可以從標準輸入流中讀取數據,并且可以把數據寫入標準輸出流中,那么就可以通過Hadoop流使用任何語言編寫MapReduce程序的map函數和reduce函數。
例如:bin/hadoop jar contrib/streaming/hadoop-streaming-0.20.203.0.jar -mapper /usr/local/hadoop/mapper.php -reducer /usr/local/hadoop/reducer.php -input test/* -output out4
Hadoop流引入的包:hadoop-streaming-0.20.203.0.jar,Hadoop根目錄下是沒有hadoop-streaming.jar的,因為streaming是一個contrib,所以要去contrib下面找,以hadoop-0.20.2為例,它在這里:
-input:指明輸入hdfs文件的路徑
-output:指明輸出hdfs文件的路徑
-mapper:指明map函數
-reducer:指明reduce函數

mapper函數

mapper.php文件,寫入如下代碼:

#!/usr/local/php/bin/php  
<?php  
$word2count = array();  
// input comes from STDIN (standard input)  
// You can this code :$stdin = fopen(“php://stdin”, “r”);  
while (($line = fgets(STDIN)) !== false) {  
    // remove leading and trailing whitespace and lowercase  
    $line = strtolower(trim($line));  
    // split the line into words while removing any empty string  
    $words = preg_split('/\W/', $line, 0, PREG_SPLIT_NO_EMPTY);  
    // increase counters  
    foreach ($words as $word) {  
        $word2count[$word] += 1;  
    }  
}  
// write the results to STDOUT (standard output)  
// what we output here will be the input for the  
// Reduce step, i.e. the input for reducer.py  
foreach ($word2count as $word => $count) {  
    // tab-delimited  
    echo $word, chr(9), $count, PHP_EOL;  
}  
?>

這段代碼的大致意思是:把輸入的每行文本中的單詞找出來,并以”

             hello    1
             world  1″

這樣的形式輸出出來。

和之前寫的PHP基本沒有什么不同,對吧,可能稍微讓你感到陌生有兩個地方:

PHP作為可執行程序

第一行的

#!/usr/local/php/bin/php

告訴linux,要用#!/usr/local/php/bin/php這個程序作為以下代碼的解釋器。寫過linux shell的人應該很熟悉這種寫法了,每個shell腳本的第一行都是這樣: #!/bin/bash, #!/usr/bin/python

有了這一行,保存好這個文件以后,就可以像這樣直接把mapper.php當作cat, grep一樣的命令執行了:./mapper.php

使用stdin接收輸入

PHP支持多種參數傳入的方法,大家最熟悉的應該是從$_GET, $_POST超全局變量里面取通過Web傳遞的參數,次之是從$_SERVER['argv']里取通過命令行傳入的參數,這里,采用的是標準輸入stdin

它的使用效果是:

在linux控制臺輸入 ./mapper.php

mapper.php運行,控制臺進入等候用戶鍵盤輸入狀態

用戶通過鍵盤輸入文本

用戶按下Ctrl + D終止輸入,mapper.php開始執行真正的業務邏輯,并將執行結果輸出

那么stdout在哪呢?print本身已經就是stdout啦,跟我們以前寫web程序和CLI腳本沒有任何不同。

reducer函數

創建reducer.php文件,寫入如下代碼:

#!/usr/local/php/bin/php  
<?php  
$word2count = array();  
// input comes from STDIN  
while (($line = fgets(STDIN)) !== false) {  
    // remove leading and trailing whitespace  
    $line = trim($line);  
    // parse the input we got from mapper.php  
    list($word, $count) = explode(chr(9), $line);  
    // convert count (currently a string) to int  
    $count = intval($count);  
    // sum counts  
    if ($count > 0) $word2count[$word] += $count;  
}  
// sort the words lexigraphically  
//  
// this set is NOT required, we just do it so that our  
// final output will look more like the official Hadoop  
// word count examples  
ksort($word2count);  
// write the results to STDOUT (standard output)  
foreach ($word2count as $word => $count) {  
    echo $word, chr(9), $count, PHP_EOL;  
}  
?>

這段代碼的大意是統計每個單詞出現了多少次數,并以”

hello   2

world  1″

這樣的形式輸出

用Hadoop來運行

把文件放入 Hadoop 的 DFS 中:

bin/hadoop dfs -put test.log test

執行 php 程序處理這些文本(以Streaming方式執行PHP mapreduce程序:):

bin/hadoop jar contrib/streaming/hadoop-streaming-0.20.203.0.jar -mapper /usr/local/hadoop/mapper.php -reducer /usr/local/hadoop/reducer.php -input test/* -output out

注意:

1) input和output目錄是在hdfs上的路徑

2) mapper和reducer是在本地機器的路徑,一定要寫絕對路徑,不要寫相對路徑,以免到時候hadoop報錯說找不到mapreduce程序

3 ) mapper.php 和 reducer.php 必須復制到所有 DataNode 服務器上的相同路徑下, 所有的服務器都已經安裝php.且安裝路徑一樣.

查看結果

bin/hadoop d fs -cat /tmp/out/part-00000

轉自:http://blog.csdn.net/hguisu/article/details/7263746

原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/3084

(0)
s19930811s19930811
上一篇 2015-04-13
下一篇 2015-04-13

相關推薦

  • M20-1 8月3號作業

    1、三種權限rwx對文件和目錄的不同意義 2、umask和acl mask 的區別和聯系 3、三種特殊權限的應用場景和作用 4、設置user1,使之新建文件權限為rw——- 5、設置/testdir/f1的權限,使user1用戶不可以讀寫執行,g1組可以讀寫 /testdir/dir的權限,使新建文件自動具有acl權限:user1:r…

    Linux干貨 2016-08-05
  • linux磁盤管理

    硬盤接口類型:         IDE:并口,133M/s;100個IO/s        SCSI:并口,UltraSCSI320,320M/s UltraSCSI640 640M/s 150-200IO/s&nbsp…

    Linux干貨 2016-08-29
  • ELK+RabbitMQ架構處理nginx及tomcat日志

    前言       查看日志的傳統方法是:登錄操作系統,使用命令工具如cat、tail、sed、awk、grep等等進行過濾輸出后分析,處理少量日志還好,日志量大處理效率就沒那么高了。而且很多情況下開發人員需要查看并分析日志進行排錯,但他們對Linux命令又不是太熟悉,而且有時候又不能賦予他們服務器權限,更多時…

    Linux干貨 2016-08-02
  • 蕭田國給你五個2017GOPS北京站的參會理由!

    2017年7月28日,GOPS全球運維大會即將開幕,發起人蕭田國將在主會場發表題為《運維如何延續自己的職業生涯》演講,參加第七屆北京站您會有哪些收益? 收益一: 【長達半天時間的培訓式演講】讓您系統性掌握頂級互聯網自動化運維體系 收益二: 【騰訊智能運維】傳奇背后的細節,聽了才知道 收益三: 與Facebook、Twitter、BATJ等運維大咖【面對面深度…

    Linux干貨 2017-07-24
  • 網絡班N22期第三周博客作業

    一、列出當前系統所有已經登錄的用戶名,且同一個用戶登錄多次只顯示一次 [root@bogon ~]# w  15:17:44 up 15:28,  2 users,  load average: 0.00, 0.00, …

    Linux干貨 2016-08-29
  • 進程管理工具

    進程管理工具 kill man 7 signal 1) SIGHUP: 無須關閉進程而讓其重讀配置文件 kill -1 進程編號 2) SIGINT: 中止正在運行的進程;相當于Ctrl+c 9) SIGKILL: 殺死正在運行的進程 再生進程 kill -9 殺不掉 15) SIGTERM:終止正在運行的進程 kill -15/或不寫(默認) +進程編號?!?/p>

    Linux干貨 2016-09-11
欧美性久久久久