淺析海量數據處理問題

生活中我們經常會遇到一些海量數據處理的問題,那麼怎樣的問題就算是海量數據了呢?來看以下這幾個問題:

  1. 給定一個大小超過 100G 的文件, 其中存在 IP 地址, 找到其中出現次數最多的 IP 地址 。
  2. 給定100億個整數, 找到其中只出現一次的整數(位圖變形, 用兩位來表示次數)。
  3. 有兩個文件, 分別有100億個query(查詢詞, 字符串), 只有1G內存, 找到兩個文件的交集。
  4. 給上千個文件, 每個文件大小爲1K - 100M, 設計算法找到某個詞存在在哪些文件中。

首先第一個問題很明確有100G的數據;第二個問題100億個整數所佔的空間大小是:100億*4byte = 40G;第三個問題100億也就是10G……要知道我們日常使用的電腦也就是4G、8G的內存大小,遠不能滿足這裏的100G、40G……的數據處理的需求。但是我們又必須要處理類似這樣的問題,難道就束手無策了麼!!!
爲了解決類似這樣的問題,我們可以藉助之前學的哈希表,位圖,布隆過濾器這樣的數據結構,接下來我們來了解一下相關知識。

哈希表
詳情請移步:哈希表

位圖
詳情請移步:位圖

布隆過濾器
詳情請移步:布隆過濾器

哈希切分

所謂的切分就很好理解,就是將一個東西切分開,將一個整體劃分爲多個更小的小整體。那麼這裏的哈希切分又是什麼操作呢?提到哈希我們就要想到這其中使用了哈希函數,同樣 的哈希切分,也需要用到哈希函數,只不過我們這裏使用哈希函數的目的在於將一個大文件分割成多個小文件。具體做法就是,我們通過哈希函數計算大文件中的每一個數據的哈希地址,將哈希地址相同的數據存放到同一個地方,所以這裏的哈希地址也就是我們新的存放數據的地方(小文件)的編號,這就叫做哈希切分,哈希切分達到的最終的目的就是將相同規律(比如說相同的IP地址,相同的單詞)的數據一定是存放在同一個文件中,但同時該文件中也會有其他的不符合同一規律的數據。

瞭解完相關知識,現在我們就來解決一下先前提到的4個海量數據問題的處理。

1、給定一個大小超過 100G 的文件, 其中存在 IP 地址, 找到其中出現次數最多的 IP 地址(hash文件切分) 。

答:首先我們看到100G的數據,肯定是不能直接處理的。
那麼我們就可以考慮使用哈希切分的方法,先將這100G的數據進行切分,切分完成以後就會有多個小文件,按照題目的要求,我們切分完以後,IP相同的一定都在同一個文件中。現在我們就可以藉助哈希表,哈希表存在一個鍵值對(key和value:初始化均爲0)。依次遍歷每一個小文件,讀取其中的數據,通過哈希函數計算哈希地址,如果當前數據還沒有存入(對應的key爲0)則將對應的哈希地址的key置爲1,value值加1。如果發現數據已經被存入過了,則就直接將對應位置的value(出現次數)值加1即可。所有的小文件中的數據遍歷完成以後,所有的ip地址已經存入到哈希表中;最後一步,根據哈希表中的value(ip地址出現的次數)進行排序,記錄當前出現次數最多的ip地址即可。

2、給定100億個整數, 找到其中只出現一次的整數(位圖變形, 用兩位來表示次數)。

答:此時我們可以採用位圖來解決。之前我們實現的位圖是用一位bit位來標識一個數據是否存在(bit位爲1)或者不存在(bit位爲0),顯然我們繼續採用這樣的設計並不能解決我們的問題,此時我們只需要擴展一下,用兩個bit位。兩個bit位就有4種狀態:00->表示沒有出現,01->表示出現一次,10和11則表示出現的次數超過1次。接下來我們就將處理數據(對應到位圖當中),處理完成以後顯然我們就可以很輕鬆的知道誰是隻出現一次的數據。

3、有兩個文件, 分別有100億個query(查詢詞, 字符串), 只有1G內存, 找到兩個文件的交集(hash文件切分 + 布隆過濾器)。

答:首先我們分析過數據規模很大,沒有辦法直接處理。那麼我們先採用哈希切分減小問題規模。採用哈希切分將兩個文件切分成多個文件,切分完畢以後,就有兩組多個小文件
(f1.1,f1.2,f1.3,f1.4,f1.5……和f2.1,f2.2,f2.3,f2.4,f2.5……)
接下來我們將其中一組所有小文件的數據採用布隆過濾器存儲,然後在處理第二組所有的小文件中的數據,可想而知,當我們在處理第二組小文件中的數據,如果遇到了相同的數據我們一定就會發現(這裏布隆過濾器的作用就是判斷某字符串是否存在於一堆數據中),那麼當我們發現遇到相同的query就直接將該query放入一個保存最終結果的文件中即可,第二組所有的小文件中的數據處理完畢我們也就找出了這兩個文件的交集。

4、給上千個文件, 每個文件大小爲1K - 100M, 設計算法找到某個詞存在在哪些文件中(倒排索引)。

這裏我們先來看一下倒排索引。(注意這裏說的倒排和正排索引只是一個相對的概念,一個叫正排索引那麼剩下的這一個就叫做倒排索引)
這裏寫圖片描述

答:1、首先我們先將每個文件的數據對應的存到一個布隆過濾器中(注意:數據存儲完畢以後我們將得到上千個布隆過濾器,每一個文件對應一個布隆過濾器)。
2、然後我們在讀取每一個布隆過濾器中的詞,並且記錄每一個詞對應的所在文件,用一個文件(info)保存詞和其所對應的文件信息。(倒排索引)
3、現在我們已經得到了所有的詞,那麼將這些詞分爲幾個小部分,分別存儲到布隆過濾器中(如果單詞數量足夠大,又u只將其存儲到一個布隆過濾器中的話,可能內存會不夠用)。
4、現在我們拿到一個單詞需要判斷他存在於哪些文件中,那麼我們就先在存儲單詞的布隆過濾器查找(布隆過濾器的基本操作:查找某個字符串是否存在),該單詞是否存在:
4.1如果不存在則取下一個存儲單詞的布隆過濾器查找,如果所有的布隆過濾器都查找完了並且都沒有找到該單詞,那就說明該單詞在這上千個文件中沒有出現過;
4.2如果我們在某一個存儲單詞的布隆過濾器中找到了該單詞,就說明該單詞在這上千個文件中出現過。
5、此時我們就可以去info文件中查找到該單詞,那麼也就知道該單詞在哪些文件中出現過了。

總結一下,處理海量數據的思路,如下圖:
這裏寫圖片描述

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