答案
通过Hadoop的MapReduce功能是可以正常运行PHP程序的。
需要通过以下步骤:
1、安装Hadoop
在集群的每台机器上安装Hadoop,保证目录结构和配置文件一致(可以在一台服务器上安装好复制到另外的服务器上),参考:怎么在CentOS Linux 8 上安装Hadoop?
2、安装PHP
在集群的每台机器上安装PHP,并保持目录结构和配置文件一致,参考:怎么在CentOS Linux 8 上安装PHP?
本文假定你已经做好了上述安装,如果没有做好,可以点击上述链接查看相关参考资料。
3、编写Mapper程序
以下命令执行用root用户:
mkdir -p /wwwroot/hadoop
vi /wwwroot/hadoop/mapper.php
内容如下:
#!/usr/bin/php
<?php
ini_set('memory_limit', '-1'); //内存使用不做限制,限制内存的事情交给系统自己解决
$word2count = array();
//STDIN (标准输入) = fopen(“php://stdin”, “r”);
//一行一行的读入数据
while (($line = fgets(STDIN)) !== false)
{
//删除前后的空格,字符转为小写
$line = strtolower(trim($line));
//“\W匹配:任意个非单词字符”
//通过“非单词字符”分割句子为“单词字符”
// PREG_SPLIT_NO_EMPTY返回分隔后的非空部分
$words = preg_split('/\W/', $line, 0, PREG_SPLIT_NO_EMPTY);
//单词计数增加
foreach ($words as $word)
{
if(!isset($word2count[$word]))
{
$word2count[$word] = 0;
}
$word2count[$word] += 1;
}
}
//输出结果到STDOUT(标准输出)
//我们这里的输出就是Reduce的输入
//即:reducer .php的输入
foreach ($word2count as $word => $count)
{
// PHP_EOL:换行符号,unix系列输出\n,windows系列输出\r\n,mac用输出\r
// chr(9):制表符分隔tab-delimited
echo $word, chr(9), $count, PHP_EOL;
}
这段代码的大致意思是:把输入的每行文本中的单词找出来,并以:
zoo 1
hello 3
world 5
这样的形式输出出来。
4、编写Reducer程序
以下命令执行用root用户:
vi /wwwroot/hadoop/reducer.php
内容如下:
#!/usr/bin/php
<?php
ini_set('memory_limit', '-1'); //内存使用不做限制,限制内存的事情交给系统自己解决
$word2count = array();
//STDIN (标准输入) = fopen(“php://stdin”, “r”);
//一行一行的读入数据
while (($line = fgets(STDIN)) !== false) {
//删除两头的空格
$line = trim($line);
//分析我们从mapper.php获得的输入
list($word, $count) = explode(chr(9), $line);
//将count(当前为字符串)转换为int
$count = intval($count);
//计算单词的数量总和
if ($count > 0) $word2count[$word] += $count;
}
//按词汇分类sort the words lexigraphically
//这个集合不是必需的,我们这样做只是为了
//使我们的最终输出看起来更像官方的Hadoop单词计数示例
// ksort() 函数对关联数组按照键名进行升序排序。
ksort($word2count);
//输出结果到STDOUT(标准输出)
foreach ($word2count as $word => $count)
{
echo $word, chr(9), $count, PHP_EOL;
}
这段代码的大意是汇总各Mapper的统计结果,最终得出每个单词出现了多少次数,排序后以:
hello 2
world 1
zoo 5
这样的形式输出,接受的输入方式“hello 1”,也就是mapper.php输出的方式。
5、执行PHP的MapReduce
这些命令执行用root用户:
chown -R hadoop:hadoop /wwwroot/hadoop
chmod +x /wwwroot/hadoop/mapper.php /wwwroot/hadoop/reducer.php
利用rsync将php代码同步到所有服务器上,确认每台机器上都有了以后,执行以下命令。
这些命令执行用hadoop用户:
su hadoop
mkdir ~/test
cd ~/test
echo 'Hello world! Hello everyone.' > tt.log
hdfs dfs -mkdir /input #在Hadoop的hdfs上创建目录/input
hdfs dfs -put tt.log /input #将要统计的文件上传到hdfs的/input上
hdfs dfs -ls /input #上传完毕,查看文件列表
hadoop jar /home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-3.2.1.jar -mapper /wwwroot/hadoop/mapper.php -reducer /wwwroot/hadoop/reducer.php -input /input/* -output /output
hdfs dfs -ls /output #查看结果文件列表
hdfs dfs -cat /output/success #查看结果文件内容,success要改成你看到的真实的名字
hdfs dfs -get /output/success #下载结果文件内容到本机,success要改成你看到的真实的名字