你的需求这样是解决不了的要分开处理。。比如,可将ip按第一位,写到255个文件里面,,,也可以将ip转换成数字,这样处理后续可以少用点内存分别在255个文件里面,找出前1000名因为每组至多包含2^24个不同的数【暂时不考虑ipv6】,这个内存可接受的
这样用一个数组遍历,复杂度O(n),即可找出前1000最后维护一个1000的有序数组,往里面插入数据即可,超过1000,弹出最小的那个 
=====
能给出例子代码吗?

解决方案 »

  1.   

    汗……我写的啊你说几十G甚至上T的日志文件,,,我的意思分开处理,一次解决怎么都困难吧因为ip理论个数大概2^32级别,,如果一次性,用数组保存,内存是非常可观的而且php操作,实际内存比其他一些语言是要大几倍的你是要找出频率最高的前N,所有出现过次数都要统计出来才能计算的
      

  2.   

    <?php$fp = fopen('haproxy.log.2','r');
    $line = fgets($fp);
    $line = explode(' ',$line);
    print_r($line);function read_100w($fp){
            $i=0;
            $ip_100w = array();
            while(!feof($fp)){
                    $i++;
                    if($i > 1000000) break;
                    $line = fgets($fp);
                    $line = explode(' ',$line);
                    $ip_info = $line[6];
                    if(preg_match('/(\d\.\d\.\d\.\d):(\d)\[(\d\.\d\.\d\.\d):(\d)\]\->(\d\.\d\.\d\.\d):(\d)\[(\d\.\d\.\d\.\d):(\d)\]/i',$line[6],$ip_info)){
                        $alt_ip = $ip_info[5];
                        $alt_port = $ip_info[6];
                        @$ip_100w[$alt_ip]++;
                    }
            }
            arsort($ip_100w);}
    ?>
      

  3.   

    说实话php不是干这种活的料。
      

  4.   

    <?php
    $filename = '/var/log/haproxy.log.3';
    echo $filename . ': ' . filesize($filename) . ' bytes';?>
      

  5.   

    一次读取100W条数据,内存肯定吃不消,再来几个并发,那就更不得了了,还是分段读取,按2楼说的那样,把内容放到N个文件中,读取频率最高的,这样不至于一次打开一个上T的文件
      

  6.   

    但是我切割文件磁盘空间满了,一次读一部分内存溢出了
    /var/log/haproxy.log.2: 12491488115 bytesPHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 1073741825 bytes) in /var/log/jincheng.php on line 7
      

  7.   

    那你就把php.ini中 memory_limit 的值改大点。
      

  8.   

    内存根本不够用,硬盘都满了,怎么搞,只能把log放在其他服务器,或者加大硬盘