用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 生成WML页面方法详解
Aug 09 PHP
php获取本地图片文件并生成xml文件输出具体思路
Apr 27 PHP
解析获取优酷视频真实下载地址的PHP源代码
Jun 26 PHP
一个php短网址的生成代码(仿微博短网址)
May 07 PHP
PHP中file_exists()判断中文文件名无效的解决方法
Nov 12 PHP
PHP处理数组和XML之间的互相转换
Jun 02 PHP
让ThinkPHP的模板引擎达到最佳效率的方法详解
Mar 14 PHP
一个非常实用的php文件上传类
Jul 04 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
May 08 PHP
php5对象复制、clone、浅复制与深复制实例详解
Aug 14 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
Jan 25 PHP
XAMPP升级PHP版本实现步骤解析
Sep 04 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
虫族 Zerg 热键控制
2020/03/14 星际争霸
php中static静态变量的使用方法详解
2010/06/04 PHP
php实现的ping端口函数实例
2014/11/12 PHP
PHP实现linux命令tail -f
2016/02/22 PHP
javascript window对象属性整理
2009/10/24 Javascript
js 获取radio按钮值的实例
2013/08/17 Javascript
jQuery中on()方法用法实例详解
2015/02/06 Javascript
readonly和disabled属性的区别
2015/07/26 Javascript
利用jQuery和CSS将背景图片拉伸
2015/10/16 Javascript
vue.js的安装方法
2017/05/12 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
vue-cli3 取消eslint校验代码的解决办法
2020/01/16 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
python 生成不重复的随机数的代码
2011/05/15 Python
可用于监控 mysql Master Slave 状态的python代码
2013/02/10 Python
Python代码的打包与发布详解
2014/07/30 Python
理解Python中函数的参数
2015/04/27 Python
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
Python读大数据txt
2016/03/28 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Canvas多边形绘制的实现方法
2019/08/05 HTML / CSS
野兽派官方旗舰店:THE BEAST 野兽派
2016/08/05 全球购物
应届毕业生的自我鉴定
2013/11/13 职场文书
办公室保洁员岗位职责
2013/12/02 职场文书
成绩单家长评语大全
2014/04/16 职场文书
中国梦演讲稿教师篇
2014/04/23 职场文书
学生安全承诺书
2014/05/22 职场文书
体育系毕业生自荐信
2014/06/28 职场文书
二人合伙经营协议书
2014/09/13 职场文书
2014年电厂工作总结
2014/12/04 职场文书
2015年12.4全国法制宣传日活动总结
2015/03/24 职场文书
2015年教务工作总结
2015/05/23 职场文书
高中数学课堂教学反思
2016/02/18 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书
windows安装python超详细图文教程
2021/05/21 Python
VW、VH适配移动端的解决方案与常见问题
2023/05/21 HTML / CSS