PHP/Shell大文件数据统计并且排序
来源:互联网 发布:锋芒网络剧第一季 编辑:程序博客网 时间:2024/06/08 18:40
出处:http://www.feiyan.info/50.html
诸多大互联网公司的面试都会有这么个问题,有个4G的文件,如何用只有1G内存的机器去计算文件中出现次数做多的数字(假设1行是1个数组,例如QQ号码)。如果这个文件只有4B或者几十兆,那么最简单的办法就是直接读取这个文件后进行分析统计。但是这个是4G的文件,当然也可能是几十G甚至几百G的文件,这就不是直接读取能解决了的。
同样对于如此大的文件,单纯用PHP做是肯定行不通的,我的思路是不管多大文件,首先要切割为多个应用可以承受的小文件,然后批量或者依次分析统计小文件后再把总的结果汇总后统计出符合要求的最终结果。类似于比较流行的MapReduce模型,其核心思想就是“Map(映射)”和“Reduce(化简)”,加上分布式的文件处理,当然我能理解和使用到的只有Reduce后去处理。
假设有1个10亿行的文件,每行一个6位-10位不等的QQ号码,那么我需要解决的就是计算在这10亿个QQ号码中,重复最多的前10个号码,使用下面的PHP脚本生成这个文件,很可能这个随机数中不会出现重复,但是我们假设这里面会有重复的数字出现。
1
$fp
=
fopen
(
'qq.txt'
,
'w+'
);
2
for
(
$i
=0;
$i
<1000000000;
$i
++ ){
3
$str
= mt_rand(10000,9999999999).
"\n"
;
4
fwrite(
$fp
,
$str
);
5
}
6
fclose(
$fp
);
生成文件的世界比较长,Linux下直接使用php-client运行PHP文件会比较节省时间,当然也可以使用其他方式生成文件。生成的文件大约11G。
然后使用Linux Split切割文件,切割标准为每100万行数据1个文件。
1
split
-l 1000000 -a 3 qq.txt qqfile
qq.txt被分割为名字是qqfileaaa到qqfilebml的1000个文件,每个文件11mb大小,这时再使用任何处理方法都会比较简单了。我还是使用PHP进行分析统计:
01
$results
=
array
();
02
foreach
(
glob
(
'/tmp/qq/*'
)
as
$file
){
03
$fp
=
fopen
(
$file
,
'r'
);
04
$arr
=
array
();
05
while
(
$qq
=
fgets
(
$fp
) ){
06
$qq
= trim(
$qq
);
07
isset(
$arr
[
$qq
]) ?
$arr
[
$qq
]++ :
$arr
[
$qq
]=1;
08
}
09
arsort(
$arr
);
10
//以下处理方式存在问题
11
do
{
12
$i
=0;
13
foreach
(
$arr
as
$qq
=>
$times
){
14
if
(
$i
> 10 ){
15
isset(
$results
[
$qq
]) ?
$results
[
$qq
]+=
$times
:
$results
[
$qq
]=
$times
;
16
$i
++;
17
}
else
{
18
break
;
19
}
20
}
21
}
while
(false);
22
fclose(
$fp
);
23
}
24
if
(
$results
){
25
arsort(
$results
);
26
do
{
27
$i
=0;
28
foreach
(
$results
as
$qq
=>
$times
){
29
if
(
$i
> 10 ){
30
echo
$qq
.
"\t"
.
$times
.
"\n"
;
31
$i
++;
32
}
else
{
33
break
;
34
}
35
}
36
}
while
(false);
37
}
这样每个样本取前10个,最后放到一起分析统计,不排除有个数在每个样本中都排名第11位但是总数绝对在前10的可能性,所以后面统计计算算法还需要改进。
也许有人说使用Linux中的awk和sort命令可以完成排序,但是我试了下如果是小文件还可以实现,但是11G的文件,不管是内存还是时间都无法承受。下面是我改的1个awk+sort的脚本,或许是写法有问题,求牛人指导。
1
awk
-F
'\\@'
'{name[$1]++ } END {for (count in name) print name[count],count}'
qq.txt |
sort
-n > 123.txt
互联网几何级增长,未来不管是大文件处理还是可能存在的大数据都存在很大的需求空间。
- PHP/Shell大文件数据统计并且排序
- shell提取一个文件中合法ip地址-并且排序和统计
- Shell 排序大文件
- 大数据:PHP职位统计(20170530)
- shell排序、统计
- php中处理大文本数据字符统计
- 统计文件中数据出现的次数并排序
- 每日数据统计排序
- php生成shell脚本并且调用
- shell脚本从文件中按行读取数据,并且赋值到数组中的几种方法
- 如何通过表单上传图片数据,PHP后端获取并且保存文件数据
- shell脚本统计: netstat数据
- 大数据之使用hadoop对海量数据进行统计并排序
- 求统计文件shell脚本?
- 统计文件行数的shell
- 分割大文件SHELL
- shell分割大文件
- shell读写大文件
- 什么时候赚能大钱?(第五次——在哪里?)
- OpenOffice在Windows和Linux下启动
- COCOS2D屏幕适配
- shell学习之-sed用法解析
- C++ operator overide example
- PHP/Shell大文件数据统计并且排序
- 监听ContentProvider数据的改变
- toastmaster-250th meeting-20130706
- Struts框架下Nginx与Tomcat容器的深度整合实践
- HDU 1076 An Easy Task
- Spring技巧之活用FactoryBean
- MySQL数据库基准压力测试工具之MySQLSlap使用实例
- 抽象类的特点
- 预处理指令