用PHP和Shell写Hadoop的MapReduce程序


Posted in PHP onApril 15, 2014

使得任何支持标准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

五、shell版的Hadoop MapReduce程序

#!/bin/bash -
# 加载配置文件
source './config.sh'
# 处理命令行参数
while getopts "d:" arg
do
 case $arg in
  d)
   date=$OPTARG
  ?)
            echo "unkonw argument"
   exit 1
    esac
done
# 默认处理日期为昨天
default_date=`date -v-1d +%Y-%m-%d`
# 最终处理日期. 如果日期格式不对, 则退出执行
date=${date:-${default_date}}
if ! [[ "$date" =~ [12][0-9]{3}-(0[1-9]|1[12])-(0[1-9]|[12][0-9]|3[01]) ]]
then
 echo "invalid date(yyyy-mm-dd): $date"
 exit 1
fi
# 待处理文件
log_files=$(${hadoop_home}bin/hadoop fs -ls ${log_file_dir_in_hdfs} | awk '{print $8}' | grep $date)
# 如果待处理文件数目为零, 则退出执行
log_files_amount=$(($(echo $log_files | wc -l) + 0))
if [ $log_files_amount -lt 1 ]
then
 echo "no log files found"
 exit 0
fi
# 输入文件列表
for f in $log_files
do
 input_files_list="${input_files_list} $f"
done
function map_reduce () {
 if ${hadoop_home}bin/hadoop jar ${streaming_jar_path} -input${input_files_list} -output ${mapreduce_output_dir}${date}/${1}/ -mapper "${mapper} ${1}" -reducer "${reducer}" -file "${mapper}"
 then
  echo "streaming job done!"
 else
  exit 1
 fi
}
# 循环处理每一个bucket
for bucket in ${bucket_list[@]}
do
 map_reduce $bucket
done
PHP 相关文章推荐
php cookie 作用范围?不要在当前页面使用你的cookie
Mar 24 PHP
php的一些小问题
Jul 03 PHP
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
Apr 26 PHP
php中如何同时使用session和cookie来保存用户登录信息
Jul 05 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
Apr 05 PHP
php中get_object_vars()方法用法实例
Feb 08 PHP
php实现在站点里面添加邮件发送的功能
Apr 28 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
Nov 12 PHP
yii2使用gridView实现下拉列表筛选数据
Apr 10 PHP
php7基于递归实现删除空文件夹的方法示例
Jun 15 PHP
启用OPCache提高PHP程序性能的方法
Mar 21 PHP
phpStorm2020 注册码
Sep 17 PHP
php获取mysql字段名称和其它信息的例子
Apr 14 #PHP
PHP检测移动设备类mobile detection使用实例
Apr 14 #PHP
PHP删除数组中空值的方法介绍
Apr 14 #PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
Apr 14 #PHP
thinkphp实现数组分页示例
Apr 13 #PHP
不使用php api函数实现数组的交换排序示例
Apr 13 #PHP
php读取大文件示例分享(文件操作类)
Apr 13 #PHP
You might like
用PHP实现ODBC数据分页显示一例
2006/10/09 PHP
phpMyAdmin链接MySql错误 个人解决方案
2009/12/28 PHP
使用ThinkPHP的自动完成实现无限级分类实例详解
2016/09/02 PHP
PDO的安全处理与事物处理方法
2016/10/31 PHP
PHP使用函数用法详解
2018/09/30 PHP
java解析json方法总结
2019/05/16 PHP
PHP抽象类和接口用法实例详解
2019/07/20 PHP
laravel接管Dingo-api和默认的错误处理方式
2019/10/25 PHP
关于用Jquery的height()、width()计算动态插入的IMG标签的宽高的问题
2010/12/08 Javascript
一道JS前端闭包面试题解析
2015/12/25 Javascript
javascript简单进制转换实现方法
2016/11/24 Javascript
JS中SetTimeout和SetInterval使用初探
2017/03/23 Javascript
深入理解JavaScript 参数按值传递
2017/05/24 Javascript
Echarts基本用法_动力节点Java学院整理
2017/08/11 Javascript
js中getBoundingClientRect的作用及兼容方案详解
2018/02/01 Javascript
webpack4的迁移的使用方法
2018/05/25 Javascript
微信小程序定位当前城市的方法
2018/07/19 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
使用Vue实现移动端左滑删除效果附源码
2019/05/16 Javascript
jQuery实现鼠标移入显示蒙版效果
2020/01/11 jQuery
JS判断浏览器类型与操作系统的方法分析
2020/04/30 Javascript
js删除对象中的某一个字段的方法实现
2021/01/11 Javascript
python多线程编程中的join函数使用心得
2014/09/02 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
2020/04/22 Python
pycharm Tab键设置成4个空格的操作
2021/02/26 Python
html5视频播放_动力节点Java学院整理
2017/07/13 HTML / CSS
应届电子商务毕业自荐书范文
2014/02/11 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
骨干教师培训方案
2014/05/06 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
2014领导干部四风问题查摆思想汇报
2014/09/13 职场文书
2014年幼儿园园务工作总结
2014/12/05 职场文书
交通事故被告代理词
2015/05/23 职场文书
贫困生证明范文
2015/06/16 职场文书
【海涛解说】暗牧也疯狂,牛蛙成配角
2022/04/01 DOTA