一類問題,典型問題一般如下:
1、給出超大文件,比如100T,每一行是一個訪問ip/查詢關鍵字等,計算頻率最高的前100個。
2、給出超大文件,比如100T,第一行是一個值,計算第N個。
特點:
1、數據非常大,無法用內存加載。
2、數據無序。
3、結果順序相關。
初步思路:一直在思考怎麼用流式的一次遍歷就直接出結果,無果。算法拼的就是經驗,沒搞過就很麻煩。
有效思路:hash劃分,縮小量級,小量級下做有序處理,然後定位到具體的分片之後,重複這個過程,直到量級很小時,排序。
例如找出100T IP數據第1000個數,思路如下:
1、先計算一下內存使用。如果是1G,做hash計數,約1G/4字節=2^28方。
2、遍歷一次文件,ip轉換爲整數,取前28位,在hash表計數,將將數據存入獨立的文件。如果是字符串,可以正常取前28位(近4字符)。
3、統計之後,hash桶排序,如果足夠離散,也可以直接遍歷28bit位數,從命中開始找。確定第1000個在哪個桶。
比如按從小開始,桶計數分別是300,400,500,300,則第1000個在500桶中。
4、針對選定的桶,如果文件過大,重複上述過程,重複過程中注意忽略已經使用的前28位。對ip來說,只能取後4位了。
5、如果文件不大了,則直接排序,計算精確的位置,比如上面的數據,前3個桶相加是700,第1000是500桶的第300個。
對於前N問題,hash分片之後,每個桶分別獨立計算前N個,然後再合併,排序,選擇最終的結果。