• 技术文章 >php教程 >PHP源码

    PHP/Shell大文件数据统计并且排序

    2016-06-08 17:23:55原创558
    本文章来给各位同学介绍一个简单的PHP/Shell大文件数据统计并且排序实现程序,各位同学可参考使用哦。

    诸多大互联网公司的面试都会有这么个问题,有个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


    互联网几何级增长,未来不管是大文件处理还是可能存在的大数据都存在很大的需求空间

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:nbsp results qq quot times
    上一篇:PHP中多字节字符的preg_match_all 下一篇:PHP Session和Javascript实现文件上传进度条
    php培训_php实战培训【立即报名】-php中文网第20期

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• PHP实现的购物车类实例_php技巧• 将PHP数组转成XML• PHP 截取中文字符串(支持多种编码)• 收藏PHP常用自定义函数• PHP实现301跳转,及延时跳转代码
    1/1

    PHP中文网