PHP几个几十个G大文件数据统计并且排序处理
诸多大互联网公司的面试都会有这么个问题,有个4G的文件,如何用只有1G内存的机器去计算文件中出现次数最多的数字(假设1行是1个数组,例如QQ号 码)。如果这个文件只有4B或者几十兆,那么最简单的办法就是直接读取这个文件后进行分析统计。但是这个是4G的文件,当然也可能是几十G甚至几百G的文 件,这就不是直接读取能解决了的。
同样对于如此大的文件,单纯用PHP做是肯定行不通的,我的思路是不管多大文件,首先要切割为多个应用可以承受的小文件,然后批量或者依次分析统计小文件后再把总的结果汇总后统计出符合要求的最终结果。类似于比较流行的MapReduce模型,其核心思想就是“Map(映射)”和“Reduce(化简)”,加上分布式的文件处理,当然我能理解和使用到的只有Reduce后去处理。
假设有1个10亿行的文件,每行一个6位-10位不等的QQ号码,那么我需要解决的就是计算在这10亿个QQ号码中,重复最多的前10个号码,使用下面的PHP脚本生成这个文件,很可能这个随机数中不会出现重复,但是我们假设这里面会有重复的数字出现。
$fp = fopen('qq.txt','w+');
for( $i=0; $i<1000000000; $i++ ){
$str = mt_rand(10000,9999999999)."\n";
fwrite($fp,$str);
}
fclose($fp);
生成文件的世界比较长,Linux下直接使用php-client运行PHP文件会比较节省时间,当然也可以使用其他方式生成文件。生成的文件大约11G。
然后使用Linux Split切割文件,切割标准为每100万行数据1个文件。
split -l 1000000 -a 3 qq.txt qqfile
qq.txt被分割为名字是qqfileaaa到qqfilebml的1000个文件,每个文件11mb大小,这时再使用任何处理方法都会比较简单了。我还是使用PHP进行分析统计:
$results = array();
foreach( glob('/tmp/qq/*') as $file ){
$fp = fopen($file,'r');
$arr = array();
while( $qq = fgets($fp) ){
$qq = trim($qq);
isset($arr[$qq]) ? $arr[$qq]++ : $arr[$qq]=1;
}
arsort($arr);
//以下处理方式存在问题
do{
$i=0;
foreach( $arr as $qq=>$times ){
if( $i > 10 ){
isset($results[$qq]) ? $results[$qq]+=$times : $results[$qq]=$times;
$i++;
} else {
break;
}
}
} while(false);
fclose($fp);
}
if( $results ){
arsort($results);
do{
$i=0;
foreach( $results as $qq=>$times ){
if( $i > 10 ){
echo $qq . "\t" . $times . "\n";
$i++;
} else {
break;
}
}
} while(false);
}
这样每个样本取前10个,最后放到一起分析统计,不排除有个数在每个样本中都排名第11位但是总数绝对在前10的可能性,所以后面统计计算算法还需要改进。
也许有人说使用Linux中的awk和sort命令可以完成排序,但是我试了下如果是小文件还可以实现,但是11G的文件,不管是内存还是时间都无法承受。下面是我改的1个awk+sort的脚本,或许是写法有问题,求牛人指导。
awk -F '\\@' '{name[$1]++ } END {for (count in name) print name[count],count}' qq.txt |sort -n > 123.txt
awk -F '\\@' '{name[$1]++ } END {for (count in name) print name[count],count}' qq.txt |sort -n > 123.txt
出处:http://www.feiyan.info/50.html
PHP几个几十个G大文件数据统计并且排序处理的更多相关文章
- Java内存映射,上G大文件轻松处理
内存映射文件(Memory-mapped File),指的是将一段虚拟内存逐字节映射于一个文件,使得应用程序处理文件如同访问主内存(但在真正使用到这些数据前却不会消耗物理内存,也不会有读写磁盘的操作) ...
- Java NIO内存映射---上G大文件处理(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果 ...
- C#windows桌面应用小程序制作——大文件数据分段解析存储
现在的任务就是做一个大文件解析的桌面应用小程序,具体需求就是:将一个很大的文件里的数据按一定标志拆分然后分别保存到某个文件夹下面. 解析的文件内容为以下内容: windows 应用小程序界面 具体代码 ...
- Sybase IQ如何将大文件数据迅速加载到数据库
试想一下,如果一个文件5G.10G甚至更大.如何将它迅速地加载到数据库指定的表呢?我们看看Sybase IQ是如何迅速地将表的数据加载到数据库的. 数据文件格式: 1440,2011-01-09 00 ...
- 用php导入10W条+ 级别的csv大文件数据到mysql。导出10W+级别数据到csv文件
转自:http://blog.csdn.net/think2me/article/details/12999907 1. 说说csv 和 Excel 这两者都是我们平时导出或者导入数据一般用到的载体. ...
- PHP实现CSV大文件数据导入到MYSQL数据库
<?php $db_host="192.168.1.10"; $db_user="root"; $db_psw="11111"; $d ...
- rsync增量传输大文件优化技巧
问题 rsync用来同步数据非常的好用,特别是增量同步.但是有一种情况如果不增加特定的参数就不是很好用了.比如你要同步多个几十个G的文件,然后网络突然断开了一下,这时候你重新启动增量同步.但是发现等了 ...
- 【.Net】 大文件可使用的文本分组统计工具(附带源码,原创)
本工具可实现的效果: 1.读取大文件(大于1GB) 2.根据分隔符分割后的列分组 3.速度快. 4.处理过程中,可以随时停止处理,操作不卡死. 5.有对当前内存的实时监测,避免过多占用内存,影响系统运 ...
- python 下载大文件
当使用requests的get下载大文件/数据时,建议使用使用stream模式. 当把get函数的stream参数设置成False时,它会立即开始下载文件并放到内存中,如果文件过大,有可能导致内存不足 ...
随机推荐
- C# 使用 AutoResetEvent 或 ManualResetEvent 同步两个线程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Sqli-labs less 51
Less-51 本关的sql语句为 $sql="SELECT * FROM users ORDER BY '$id'"; 我们此处要进行stacked injection,要 ...
- poj 2975 Nim 博弈论
令ans=a1^a2^...^an,如果需要构造出异或值为0的数, 而且由于只能操作一堆石子,所以对于某堆石子ai,现在对于ans^ai,就是除了ai以外其他的石子 的异或值,如果ans^ai< ...
- Javascript 数组循环遍历之forEach
1. js 数组循环遍历. 数组循环变量,最先想到的就是 for(var i=0;i<count;i++)这样的方式了. 除此之外,也可以使用较简便的forEach 方式 2. forE ...
- JS加载时间线
1.创建Document对象,开始解析web页面.解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中.这个阶段document.readyState = 'loading' ...
- ant+jmeter+crontab实现自动化性能测试
准备工作: 1.下载jmeter(我下载的apache-jmeter-2.13.zip) 2.配置jmeter环境变量,即path前添加jmeter的bin路径) 3.下载ant(我使用的apache ...
- 入门命令13-字符串查找增强:findstr
http://www.cnblogs.com/doupip/archive/2011/12/23/2299210.html 在文件中寻找字符串. FINDSTR [/B] [/E] [/L] [/R] ...
- 一个tomcat上放多个webapp问题,那这多个webapp会不会竞争端口呢?不会!安全两码事
1.一个tomcat上放多个webapp问题,那这多个webapp会不会竞争端口呢?不会!安全两码事
- Hadoop基础教程之高级编程
从前面的学习中,我们了解到了MapReduce整个过程需要经过以下几个步骤: 1.输入(input):将输入数据分成一个个split,并将split进一步拆成<key, value>. 2 ...
- Hibernate笔记——关联关系配置(一对多、一对一和多对多)
原文:http://www.cnblogs.com/otomedaybreak/archive/2012/01/20/2327695.html ============================ ...