大資料與演算法系列之海量資料查詢演算法

2021-08-20 11:56:20 字數 2899 閱讀 9845

在某些時候,可能會涉及在海量資料中的查詢,如果採用通常的做法,則很難達到一定的效果,在實際工程實踐中,海量資料的查詢效能很肯恩鬼成為整個系統的效能瓶頸,在海量資料中的查詢包括基於布隆過濾器的方式,以及基於倒排索引的資料結構。

布隆過濾器(bloom filter)是2023年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,確定是有一定的誤判率和刪除困難。

概念如果要判斷乙個元素是不是在乙個集合中,通常的方法是將集合中所有的元素儲存起來,然後通過比較去確定,鍊錶,樹,雜湊表等資料結構都是使用這種思路。但是隨著集合中元素的增加,需要的儲存空間越來越大,同時,檢索速度也越來越慢,上述三種結構的檢索時間複雜度分別為o(n),o(logn),o(n/k).

布隆過濾器的原理是,當乙個元素加入集合中時,通過k個雜湊函式將這個元素對映為乙個位組數中的k個點,把他們置為1,檢索時,只要檢視這些點是不是都是1就大約知道集合中有沒有它了:如果這些點有任何乙個是0,則被檢測元素一定不再元素中,如果都是1,則被檢測元素很可能在,這就是布隆過濾器的基本思想。

相比於其他的資料結構,布隆過濾器在空間和時間方面有巨大的優勢,布隆過濾器儲存空間和插入/查詢時間都是常數(o(k))。另外,雜湊函式相互之間沒有關係,方便由硬體並行實現,布隆過濾器本身不需要儲存元素,在某些對保密性要求非常嚴格的場合有優勢。此外,布隆過濾器可以表示全集,其他任何資料結構都沒有此功能。

但是布隆過濾器的確定和優點一樣明顯,誤算率就是其中之一。隨著存入的元素數量增加,誤算率隨之增加,但是如果元素數量太少,則使用雜湊表即可。

另外,一般情況下不能從布隆過濾器中刪除元素,例如,把位陣列變成整數陣列,沒插入乙個元素則計數器相應的加1,這樣刪除元素時將計數器減掉就可以了,然後要保證安全的刪除元素並非如此簡單,首先必須保證刪除的元素的確在布隆過濾器裡面,而這一點單憑這個過濾器是無法保證的,另外,計數器迴繞也會造成問題。

在降低誤算率方面,也有不少工作,因此出現了很過布隆過濾器的變種。

應用:搜尋引擎中的url過濾

假設要編寫乙個網路爬蟲程式,由於網路間的鏈結錯綜複雜,爬蟲在網路間爬行很可能會形成「環」,為了避免形成「環」,就需要知道爬蟲程式已經訪問過哪些url。給乙個url,怎樣知道爬蟲程式是否已經訪問過呢?有一下幾種方法。

將訪問過的url儲存到資料庫

用hashset將訪問過的url儲存起來,只需接近o(1)的代價就可以查到乙個url是否被訪問過了。

url經過md5或sha-1等單向雜湊後再儲存到 hash set或資料庫。

bit-map方法。建立乙個 bitset,將每個url經過乙個雜湊函式對映到某一位。

方法1~3都是將訪問過的url完整儲存,方法(4)則只標記url的乙個對映位。以上方法在資料量較小的情況下都能完美解決問題,但是當資料量變得非常龐大時問題就來了。

方法(1)的缺點:資料量變得非常龐大後,關係型資料庫查詢的效率會變得很低。而且每來乙個url就啟動一次資料庫查詢是不是太小題大做了。

方法(2)的缺點:太消耗記憶體。隨著url的增多,占用的記憶體會越來越多。就算只有1億個url,每個url僅為50bit,就需要5gb記憶體。

方法(3):由於字串經過md5處理後的資訊摘要長度只有128bit,sha-1處理後也只有160bit,因此方法(3)比方法(2)節省了好幾倍的記憶體。

方法(4)消耗記憶體是相對較小的,但缺點是單一雜湊函式發生衝突的概率太高。還記得資料結構課上學過的hash表衝突的各種解決方法嗎?若要降低衝突發生的概率到1%,就要將 bitset的長度設定為url個數的100倍。

除了url去重外,在海量文字中查詢某個詞語的出現也會採用布隆過濾器。由於單詞數量的巨大,需要在超過一億的數量級上判斷某個單詞是否存在,因此需要一種極其高效的方式去實現。傳統的方法是,將所有資料存放在乙個集合裡面,或許是鍊錶,或許是樹或許是雜湊表,然後分別通過時間複雜度o(n),o(lgn),o(n/k)找到。雖然雜湊表的效能已經很好,但是依然覺得在億級以上資料查詢不是很理想。

布隆過濾器是由乙個很長的二進位制向量及多個隨機函式組成的。當新增乙個元素到大集合中時,需要利用n個雜湊方法將此元素對映為n個點,這n個點組成乙個位陣列形式,且它們的值設定為1。當判斷是否存在時,只需判斷新產生的位陣列是否均為1即可,可按照「&」運算進行。如果「&」運算的最終結果為0,則需要判斷的元素一定不存在。反之,結果為1,則說明該元素存在。可利用布隆過濾器的基本思想來為語料庫中片語是否存在進行判斷。

索引是一種用於資料快速查詢的資料結構,雜湊表、二分查詢、分塊查詢也可以視為一種索引,這類索引的價值在於在較短的時間內獲得最相關、最全、最深的資料集合。在通常使用的索引中,大多是基於順序表、雜湊表或b+樹的索引。倒排索引( invertedindex)主要用於資訊檢索領域,它是其中最常用的資料索引儲存結構,被用來儲存文件集合中某個單詞對應的文件集合及單詞在檔案中存在的位置,因此也稱為反向索引,與其相對應的是正向索引,正向索引用於儲存每個檔案的單詞列表,並記錄其位置,以下表中的檔案及對應句子內容為例

在資訊檢索中,可以根據檔案生成的倒排索引,當使用者檢索「資料演算法」時,會將詞語對應的檔案集合取出,並且會根據相關性對檔案進行排序處理,得到最終檢索後的結果。

此外,在某些檢索系統中,可能會有不儲存詞語在檔案中位置的情況,但是目前大多數檢索系統都會儲存,主要基於兩個原因:

雖然雜湊表等其他資料結構也能夠較好地處理資料索引問題,但是對於資料量較大的情況,雜湊表的效能也會受到較大的影響。在資料量較大時,會將海量資料進行分布式索引,分布式雜湊表和分布式倒排索引則是較好的處理方式,但從檢索的綜合評價角度,分布式索引更為合適。

演算法系列之十八 海量資料處理之BitMap

一 簡介 所謂的bitmap就是用乙個bit位來標記某個元素對應的value,而key即是該元素。由於採用了bit為單位來儲存資料,因此在儲存空間方面,可以大大節省。二 基本思想 我們用乙個具體的例子來講解,假設我們要對0 7內的5個元素 4,7,2,5,3 排序 這裡假設這些元素沒有重複 那麼我們...

海量資料查詢唯一資料問題

常見的問題有以下幾類 問題一 有101個數,為 1,100 之間的數,其中乙個數是重複的,如何尋找這個重複的數,其時間複雜度和空間複雜度是多少?方法 利用和 sum1 1 2 3 99 sum2 a 0 a 1 a 99 sum2 sum1 重複的那個值 int onlyonerepeate int...

多執行緒生成海量資料和多執行緒海量資料查詢

using system using system.collections.generic using system.linq using system.text using system.threading using system.diagnostics namespace multithrea...