海量數據處理相關算法簡介

一、Hash映射/分治,數組的特點是尋址容易,但是插入刪除困難,鏈表的特點是尋址困難,但是插入刪除容易。而哈希表就是這兩者的結合,尋址和插入刪除都容易。左邊是一個數組,數組每個成員包含一個指針指向一個鏈表的頭。如圖所示的就是一種求模數散列法。index=value%16


統計某日訪問谷歌官網最多的IP,數據肯定是{時間:IP}形式的,只需統計每個IP出現的次數返回最大的即可。但是數據量往往非常大,內存加載不了,使用哈希函數/哈希映射將大文件分成一個個的小文件。這時候每個文件就可以加載進內存,統計每個小文件出現次數最多的IP,最後將所有小文件出現次數最多的IP互相比較得出整體訪問官網次數最多的IP。

哈希映射,例如把大文件分成10000個小文件,對每個IP模10000,得到的值爲k(0~9999),放入第k個文件當中。同時相同的IP一定會得到相同的k值,且都被存入k文件中,保證了每個IP都只存在於一個文件當中

二、Hash映射/分治

搜索引擎,現有1000萬條檢索字符串記錄,每條字符串1~255個字節,要求找出檢索熱度最高的10個字符串。其中去掉重複的字符串大概剩餘300萬條記錄,內存最大1G。解決方法依然是Hash映射的思想,數據總量10000000*1/4*1024字節=2500000KB=2500M=2.5G,超出內存限制。對每個字符串模3得到值k,k的範圍0~2,將數據分別存入到0、1、2三個文件當中,這樣每個文件都可以加載進內存。使用Hash統計,得到每個字符串總共檢索的次數,最後使用堆排序得出檢索熱度最高的十個字符串。

最小堆排序,用前十個字符串出現的次數構建一個最小堆,然後堆頂元素跟剩下的每個字符串作對比,如果出現次數比堆頂元素小則不調整最小堆,如果比堆頂元素大則替換堆頂元素並重新調整最小堆,最終得到檢索次數最多的十個字符串。

此類問題有一個關鍵點就是相同的IP或者字符串都應該在同一個文件或者機器上,否則需要首先用Hash映射(例如取模)將相同元素映射到同一個文件下,再進行Hash統計,最後歸併排序結果(歸併排序,採用分治思想,將待排序的序列分成許多部分,每兩個部分從第一個元素開始兩兩比較得出較小值存入第三個空數組,得到一個排好序的新數組,將新數組與其他部分重複前面過程)

三、Trie樹,利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希表高(適合數據量大,重複多,但是數據種類小可以放入內存)


一個大文件,每行一個單詞,統計出現頻次最高的十個單詞。首先可以使用前面的Hash映射分治的方法,這裏介紹另外一種基於Trie樹的方法。如上所示,首先將所有單詞構建Trie樹,統計的時候檢索Trie樹是否存在這個單詞,存在則計數加一。最後使用最小堆得到十個出現頻次最高的單詞。Trie樹的時間複雜度爲O(n*length),最小堆的時間複雜度爲O[ n*lg(10) ]

四、Bitmap

Bitmap:假設有一組需要排序的數列 [4,6,9,1,2 ],因爲最大值爲9,所以需要開闢16個Bit位,大小2Byte。首先第一個元素4,應放在第五個Bit位,值設置爲1。第二個元素6應放在第七個Bit位,並將位設置爲1。最後遍歷一遍Bit域便得到【1,2,4,6,9】

假設有2.5億個整數,試找出2.5億個整數中不重複的整數。用兩個Bit位表示一個整數,沒有出現00,出現一次01,出現多次10,11沒有意義。總共2^32×2=1G內存,遍歷2.5億整數,將對應Bit位根據出現次數進行設置,最後輸出Bitmap位爲01的就可以了。

BloomFilter:假設存在AB兩個文件,各包含50億條URL,現在需要找出兩個文件中共同的URL。假設每條URL佔64字節(512Bit位),內存限制爲4G。4G內存大概相當於320億Bit位,首先將A文件中的URL映射到320億Bit位中,例如映射方法爲採用三個不同的Hash函數,得到三個不同的哈希值k1,k2,k3,並將對應Bit位設置爲1,然後從文件B中取一個URL採用同樣的三個Hash函數映射,如果得到的三個哈希值在前面的Bit位域中都設置爲1了,說明這是一個AB文件中都包含的URL。

BloomFilter是一種空間效率很高的隨機數據結構,它利用位數組很簡潔地表示一個集合,並能判斷一個元素是否屬於這個集合。它是判斷一個元素是否存在於某個集合的快速算法。BF可能會出現誤判,如果BF認爲一個元素不在集合中,那麼肯定不在。如果在集合中,那麼存在一定概率判斷錯誤。


如上所示爲一個m位的位數組,初始都爲0。假設存在集合{x1,x2,x3......xn},布隆過濾器使用k個獨立的哈希函數,它們將集合中的每個元素映射到m位數組中。在判斷y是否屬於集合時,使用k個哈希函數得到k個哈希值,然後將對應位置1,如圖y1不屬於這個集合,y2屬於這個集合。Bloom filter將集合中的元素映射到位數組中,用k(k爲哈希函數個數)個映射位是否全1表示元素在不在這個集合中。

五、MapReduce

包括map、reduce兩個過程,最經典的例子就是wordcount了。假設我們有很多篇文章,每篇文章包含很多單詞,單詞在不同文章、同一篇文章有重複。

分佈式文件系統HDFS,具有高容錯性。HBase是一個分佈式的、面向列的、可伸縮的數據庫,其建立在HDFS上。

六、堆(最大堆求前n小,最小堆求前n大)


                                                                              如圖所示就是最小堆

而二叉堆是一種完全二叉樹,其任意子樹的左右節點(如果有的話)的鍵值一定比根節點大。


二叉堆入隊過程


二叉堆出隊過程

七、雙層桶

假設有5億個int整數,找出他們的中位數。我們將int分爲2^16=65536個區域,然後統計落在各個區域裏的數,中位數就是第2.5個整數,這樣就能找出中位數在哪個區域,之後在那個區域裏再找中位數就可以了。

八、倒排索引

在前面的文本相似度計算、tf-idf、詞向量的文章中已經詳細介紹了VSM模型。漢語中構建的詞向量可能很大,可能是幾十萬維度的,這個時候計算開銷比較大。倒排索引被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射,它是文檔檢索系統中最常用的數據結構。

文檔1(D1):中國移動互聯網發展迅速
文檔2(D2):移動互聯網未來的潛力巨大
文檔3(D3):中華民族是個勤勞的民族


倒排索引數據結構彙總存儲了兩個重要信息,文檔編號和單詞出現的次數。當有一個查詢時,分詞之後根據倒排索引,得出文檔之間的相似度。注意左側的漢字可以換成GBK編碼來加快查詢速度。


參考資料:https://blog.csdn.net/he90227/article/details/38299975

                https://www.cnblogs.com/ECJTUACM-873284962/p/6910842.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章