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 

發佈了83 篇原創文章 · 獲贊 30 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章