用PHP和Shell写Hadoop的MapReduce程序
Hadoop的核心虽然是用Java编写的,但Hadoop Streaming这一小工具为Hadoop提供了流式处理支持,打破了这一局限。这使得任何支持标准输入(stdin)和标准输出(stdout)的可执行程序都能成为Hadoop的Mapper或Reducer。这种设计理念的灵活性令人惊叹。
想象一下,你习惯于使用动态语言进行编程,那么通过Hadoop Streaming,你可以轻松地使用这些语言来编写MapReduce程序。例如,在狼蚁网站SEO优化的场景中,我们可以使用PHP来实现Word Counter的MapReduce。
为了开始这个过程,首先需要找到Hadoop Streaming的jar文件。它位于Hadoop根目录的contrib/streaming文件夹内。以hadoop-0.20.2版本为例,其路径为$HADOOP_HOME/contrib/streaming/hadoop-0.20.2-streaming.jar。
接下来,我们编写Mapper部分。创建一个名为wc_mapper.php的文件,内容如下:
这个PHP文件首先通过打开标准输入流(php://stdin)来接收输入。然后,它将每行文本分割成单词,并以“word 1”的形式输出每个单词及其出现次数。
这个PHP文件有两个与众不同的地方:
首先是作为可执行程序的部分。第一行的“!/usr/bin/php”告诉Linux系统使用/usr/bin/php作为该文件的解释器。这种写法在Linux shell脚本和Python脚本中非常常见。这使得我们可以像执行cat或grep命令一样直接执行wc_mapper.php文件。
其次是使用标准输入接收输入。PHP支持多种参数传入方式,其中最常见的是通过Web传递的参数(从$_GET, $_POST超全局变量中取)和命令行参数(从$_SERVER['argv']中取)。在这里,我们使用的是标准输入stdin。这意味着当你运行wc_mapper.php时,你可以直接在控制台输入文本,按下Ctrl + D后,wc_mapper.php开始处理输入并输出结果。
这种使用PHP编写MapReduce程序的方式,不仅保持了原有编程习惯,还充分利用了Hadoop的并行处理能力。通过Hadoop Streaming,我们可以将任何支持标准IO的工具或语言与Hadoop集成,从而扩展Hadoop的生态系统并推动大数据处理的边界。在数据世界的中,让我们开始聚焦于一个特定的任务:统计单词出现的次数。为此,我们需要编写一个reducer,就像铸造一把能够剖析数据海洋的利剑。
打开你的代码编辑器,新建一个名为 `wc_reducer.php` 的文件,然后输入以下代码:
```php
!/usr/bin/php
$in = fopen("php://stdin", "r");
$results = array();
while ($line = fgets($in, 4096)) {
list($key, $value) = preg_split("/[\t\s]+/", trim($line), 2); // 使用空格或制表符分割键值对
if (isset($results[$key])) { // 如果键已存在,增加对应的值
$results[$key] += intval($value);
} else { // 如果键不存在,将其添加到结果数组中并设置其值为输入值
$results[$key] = intval($value);
}
}
fclose($in);
ksort($results); // 按照键名排序结果数组
foreach ($results as $key => $value) { // 输出结果,格式为“键名 键值”并以换行符结束
print "$key\t$value";
}
```
这段代码的核心功能是从输入流中读取数据,统计每个单词出现的次数,并按单词排序后输出统计结果。它的工作方式类似于一个数据处理的工匠,精细地雕琢着每一个数据颗粒。
接下来,我们要在Hadoop上运行这个reducer。需要上传要统计的示例文本到Hadoop的文件系统(HDFS)。使用以下命令上传文本文件:
```bash
hadoop fs -put .TXT /tmp/input
```
然后,我们可以使用Hadoop的Streaming功能以PHP执行MapReduce程序。执行以下命令时,请确保替换路径为实际的 `wc_mapper.php` 和 `wc_reducer.php` 文件路径:
```bash
hadoop jar hadoop-0.20.2-streaming.jar \
-input /tmp/input \
-output /tmp/output \
-mapper wc_mapper.php的绝对路径 \
-reducer wc_reducer.php的绝对路径
```
五、Hadoop MapReduce程序的Shell脚本之旅
在这个充满数据的时代,Hadoop MapReduce已成为大数据处理的核心工具。今天,我们将通过Shell脚本Hadoop MapReduce的魅力。
让我们先来看一个简单的脚本示例:
```bash
!/bin/bash
加载配置信息
source './config.sh'
命令行参数
while getopts "d:" arg; do
case $arg in
d) date=$OPTARG;;
) echo "未知参数" >&2; exit 1;;
esac
done
默认处理日期设为昨天
default_date=$(date -v-1d +%Y-%m-%d)
确定最终处理日期,格式不对则退出执行
if ! [[ "$date" =~ [12][0-9]{3}-(0[1-9]|1[12])-(0[1-9]|[12][0-9]|3[01]) ]]; then
echo "日期格式错误: $date" >&2; exit 1;
fi
获取待处理文件列表
log_files=$(hadoop fs -ls ${log_file_dir_in_hdfs} | awk '{print $8}' | grep $date)
if [ $(echo $log_files | wc -l) -lt 1 ]; then echo "未找到日志文件"; exit 0; fi
构建输入文件列表
for f in $log_files; do input_files_list="${input_files_list} $f"; done
定义MapReduce函数
map_reduce() {
hadoop jar ${streaming_jar_path} -input ${input_files_list} -output ${mapreduce_output_dir}${date}/${1}/ \
-mapper "${mapper}" -reducer "${reducer}" -file "${mapper}" && echo "Streaming任务完成!" || exit 1;
}
循环处理每个bucket
for bucket in ${bucket_list[@]}; do map_reduce $bucket; done
```
这个脚本首先加载配置信息,然后命令行参数以获取处理日期。接着,它检查日期格式是否正确,并获取待处理的日志文件列表。之后,脚本构建了一个输入文件列表并定义了一个MapReduce函数来处理这些文件。脚本循环处理每个bucket。整个过程通过Shell脚本自动化执行,极大地简化了Hadoop MapReduce的操作。让我们期待更多的大数据奇迹在这个强大的工具下诞生!
长沙网站设计
- 用PHP和Shell写Hadoop的MapReduce程序
- Laravel 5框架学习之子视图和表单复用
- PHP实现创建一个RPC服务操作示例
- jquery版轮播图效果和extend扩展
- Asp.net中使用文本框的值动态生成控件的方法
- jQuery实现动态表单验证时文本框抖动效果完整实
- vue-swiper的使用教程
- 基于Phantomjs生成PDF的实现方法
- 使用SVG基本操作API的实例讲解
- asp.net运算符之逻辑运算符以及其他运算符介绍与
- 浅析如何利用angular结合translate为项目实现国际化
- thinkPHP3.2实现分页自定义样式的方法
- JavaScript数组方法总结分析
- JS优化与惰性载入函数实例分析
- Vue.js学习笔记之修饰符详解
- jsp+ajax实现的局部刷新较验验证码(onblur事件触发