大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?


对于很多用户来说10G数据可能并不大,对这个数量级的数据分析能算得上是大数据吗?

当然算了,我们只是拿这个10G的数据作为一个例子,系统能处理10G的数据,理论上就能处理100G甚至是1T数据。这要看咱们的硬件配置情况和所需要耗费的时间。假如1T数据1台服务器需要5小时才能出结果,那我们用60台服务器去并行计算,可能2分钟结果就能出来了。

本文假设你已经查看过我的Hadoop大数据规划以及安装配置的文章,已经安装并配置好PHP软件,安装并配置好Rsync软件。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

PHP还能进行大数据计算呢?

当然能了。

Hadoop本身是Java写的,所以顺理成章的,给Hadoop写MapReduce,人们会自然地想到Java。但Hadoop里面有个Contrib叫做Hadoop Streaming,这是一个小工具,为Hadoop提供Streaming支持。利用该Streaming提供的API,允许用户使用任何语言编写Map函数和Reduce函数。因此,PHP也可以借助该API来进行大数据计算与分析。

另外这里面牵涉到下面这个问题。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

MapReduce是什么?

概念"Map(映射)"和"Reduce(归约)",是它的主要思想,它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。

从网上一搜就能搜到非常多的关于MapReduce的内容,写的都很好。但是不是很好理解。我根据我的理解直白的说明如下,欢迎拍砖:

1、一个超大数据文件(超过1T)切成6份(我们有6个DateNode),分别存到6台服务器上;

2、我们的计算程序分别在这6台服务器上计算自己的那份,得出结果,过程中可能会把自己的那份切成更小的份数(Hadoop默认一份为128M);

3、6台服务器计算的结果再汇总到一个服务器上,进行汇总计算,得出最终结果。

以上例子"把数据分到6台服务器并计算出结果"就是对Map(映射)最直白的其中一种解释;而"6台服务器计算结果汇总到一起,得出最终结果"就是对Reduce(归约)最直白的其中一种解释。

这么一看,是不是就没什么神秘的了呢?

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

准备一个10G的数据文件

手头不容易找到10G那么大的文本文件,那咱就自己创造一个。随便打开一个英文网站,比如Firewalld的官网blog页面:

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

页面内全选(Ctrl+A),复制(Ctrl+C),然后打开CentOS Linux 8的SSH客户端。

新建一个文件名问10G.txt的文件,然后把刚才复制的内容粘贴进去,命令如下:

<code>vi 10G.txt/<code>
大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

然后就是不断的去找英文的内容,粘贴进去,感觉差不多了,进行下一步。

因为我们不可能一直复制出10G的文字那么多,那我们就利用CentOS Linux 8,自己复制自己,最终得出这么多内容,命令如下:

<code>cat 10G.txt >> 11G.txt/<code>
<code>cat 11G.txt >> 10G.txt/<code>

不断的重复这个过程,因为每次都翻倍,文件大小呈现指数级增长,很快我们就能得到一个10G的文件了。文件大小超过500M之后,会变的有点慢,有耐心的等一下。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?


将10G.txt上传至Hadoop的分布式存储系统HDFS,执行以下命令:

查看HDFS上的根目录:

<code>hdfs dfs -ls //<code>

在HDFS的根目录下简历input目录:

<code>hdfs dfs -mkdir /input/<code>

查看input目录是否创建成功:

<code>hdfs dfs -ls //<code>

将10G.txt上传至HDFS的/input目录下:

<code>hdfs dfs -put 10G.txt /input/<code>
大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

查看10G.txt上传至/input目录是否成功:

<code>hdfs dfs -ls /input/<code>
大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

根据咱们设定的规则,HDFS会保存3个副本。也就是说咱们虽然上传了10G数据,但是HDFS会在整个系统上存储30G的数据。从上图最后一行的数据也能看的出来,第一个9.6G是咱们上传的数据量,后面的28.9G是HDFS实际存储的量。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

WEB查看一下,每台服务器上存储了大约5G的数据,6台DataNode正好大约是30G(见上图)。

上传这10G文件的时候服务器的压力还是比较大的。CPU经常在75%徘徊,64G内存已经用去将近60G,磁盘的压力也很大。从截图中也能看到,上传开始时间"22:52:54",上传结束时间"22:59:12",花费了6分18秒的时间。这就是用一台服务器来模拟8台服务器的弱点。如果是真正的8台服务器,哪怕就是普通的PC安装的Linux系统搭建的服务器,只要装上万兆(10G)的网卡,再来个10块硬盘组Raid0,时间估计能压缩到1分钟以内。因为Hadoop技术上允许一部分DataNode掉线后系统正常运行,所以可以组Raid0提供存储服务来提高系统运行性能。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

至此,这个10G的txt文件已经顺利的上传到了Hadoop的分布式存储服务HDFS上。

如果你还有多个文件要一起分析,都传到这个/input目录下即可。也就是说后面的分析程序是支持多个文件合并进行数据分析的,你不用自己手动把这几个文件合并到一个文件里面。

准备PHP数据分析程序

在集群的每台机器上安装PHP,并保持目录结构和配置文件一致,参考我的在CentOS Linux 8 上安装PHP的文章。并且已经安装并配置好了Rsync。

本文假定你已经做好了上述安装,如果没有做好,可以查看相关参考资料。

根据咱们的集群规划,主Rsync位于Hadoop222服务器,所以以下的程序编写部分我们在Hadoop222(192.168.1.222)上面操作。

编写Mapper程序

用root执行以下命令,配置好Hadoop用的PHP目录

<code>mkdir -p /wwwroot/hadoop/<code>
<code>chown -R hadoop:hadoop /wwwroot/hadoop/<code>

转为Hadoop用户执行以下操作:

<code>su hadoop/<code>
<code>vi /wwwroot/hadoop/mapper.php/<code>

输入以下内容:

#!/usr/bin/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;

}

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

这段代码的大致意思是:把输入的每行文本中的单词找出来,并以:

zoo 1

hello 3

world 5

这样的形式输出出来。

编写Reducer程序

用Hadoop用户执行以下操作:

<code>su hadoop/<code>
<code>vi /wwwroot/hadoop/reducer.php/<code>

输入以下内容:

#!/usr/bin/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;

}


大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

这段代码的大意是汇总各Mapper的统计结果,最终得出每个单词出现了多少次数,排序后以:

hello 2

world 1

zoo 5

这样的形式输出,接受的输入方式"hello 1",也就是mapper.php输出的方式。

给Mapper和Reducer赋予可执行权限。

<code>chmod +x /wwwroot/hadoop/mapper.php /wwwroot/hadoop/reducer.php/<code> 

执行PHP的MapReduce进行大数据分析

上面已经完成数据上传,代码的编写。我们要在每台服务器上查看一下,是否已经将PHP代码同步到每一台服务器上了。

在每台服务器上都执行以下命令:

<code>ll /wwwroot/hadoop//<code>
大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

必须保证每台服务器上都有上述的两个PHP文件,才能执行以下大数据计算的命令:

<code>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/<code>
大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

由于数据量比较大,所以数据计算的执行时间会比较长,需要耐心等待。

从服务器上的截图可以看到,服务器已经拿出100%的CPU资源,几乎100%的内存资源,每块硬盘轮流100%的资源,来完成咱们的大数据计算任务。

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

系统计算完毕之后,查看一下输出的结果,咱们设定的输出目录是HDFS的/output:

<code>hdfs dfs -du -h /output/<code>

把输出结果下载下来查看:

<code>hdfs dfs -get /output/part-00000/<code>

当然也可以在线查看,不过感觉不太方便,执行下述命令:

<code>hdfs dfs -cat /output/part-00000/<code>

或者这个命令:

<code>hdfs dfs -tail -f /output/part-00000/<code>


大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

从上面的截图中可以看到,为了分析这10G的数据,程序执行的开始时间是"23:26:23",程序执行的结束时间是"23:37:28",共花费了11分5秒。

上述得到的结果是:字符串"0"在文件中出现了"36366795"次,字符串"00"在文件中出现了"105411"次,依次类推,整个计算结果的文件part-00000大小是30.9K。


大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?


总结

通过以上测试可以发现,用PHP做大数据分析真的非常容易。由于Hadoop提供了MapReduce接口,我们在编写PHP程序的时候,只需要关注逻辑处理即可,分片计算的部分Hadoop帮我们搞定了。

我们使用了一台服务器虚拟成8台服务器,对10G的数据进行分析,花费了11分5秒的时间。这个时间长度在可接受的范围之内,但如果做成多台真实的服务器进行计算,时间肯定会大幅缩减。如果有条件的时候,还真想试试。


分享到:


相關文章: