TopK 问题

问题:海量日志数据,提取出某日访问百度次数最多的那个IP

分析:百度作为国内第一大搜索引擎,每天访问它的IP数量巨大,如果想一次性把所有IP数据装进内存处理,则内存容量明显不够,故针对数据太大,内存受限的情况,可以把大文件转化成(取模映射)小文件,从而大而化小,逐个处理。

换言之,先映射,而后统计,最后排序。

解法:具体分为以下3个步骤

  • 1.分而治之/hash映射
    • 首先把这一天访问百度日志的所有IP提取出来,然后逐个写入到一个大文件中,接着采用映射的方法,比如%1000,把整个大文件映射为1000个小文件。
  • 2.hash_map统计
    • 当大文件转化成了小文件,那么我们便可以采用hash_map(ip, value)来分别对1000个小文件中的IP进行频率统计,再找出每个小文件中出现频率最大的IP。
  • 3.堆/快速排序
    • 统计出1000个频率最大的IP后,依据各自频率的大小进行排序(可采取堆排序),找出那个频率最大的IP,即为所求。

:Hash取模是一种等价映射,不会存在同一个元素分散到不同小文件中去的情况,即这里采用的是%1000算法,那么同一个IP在hash后,只可能落在同一个文件中,不可能被分散的

总结:

(1)将ip地址放入多个小文件中,保证每种IP只出现在一个文件中
(2)利用hashmap统计每个小文件中IP出现的次数
(3)利用最小堆得到所有IP访问次数最多的100个

参考:

https://segmentfault.com/a/1190000019785430

https://www.kancloud.cn/kancloud/the-art-of-programming/41613

 

附加:使用shell统计出出现次数排名top10的网址

#!/bin/sh  
  
  
foo()  
{  
    if [ $# -ne 1 ];  
    then  
        echo "Usage:$0 filename";   
        exit -1  
    fi  
  
  
egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}" website | awk '{ count[$0]++ } END { printf("%-30s %s\n","wensite","count"); for(ind in count) { printf("%-30s %d\n",ind,count[ind]); } }' | sort -nrk 2 | head -n 10 >websorted2.txt;  
}  
  
  
foo website  

参考:https://www.cnblogs.com/yidaxia/p/4459682.html 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值