Hadoop中的Bloom Filter布隆過濾器介紹
布隆過濾器
布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實際上是一個很長的二進位制向量和一系列隨機對映函式。布隆過濾器用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。
基本概念
如果想判斷一個元素是不是在一個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。連結串列、樹、散列表(又叫雜湊表,Hash table)等等資料結構都是這種思路,。但是隨著集合中元素的增加,我們需要的儲存空間越來越大。同時檢索速度也越來越慢,上述三種結構的檢索時間複雜度分別為。
布隆過濾器的原理是,當一個元素被加入集合時,通過K個
例子
以垃圾郵件過濾為例子來說,當一封郵件是垃圾郵件時,通過K個雜湊函式將其對映成一個維陣列(原始值都是0)中的K個點,將這K個點置為1。遇到一封垃圾郵件就按照這個步驟來,如果垃圾郵件已經在維陣列檢索列表中,則即可識別出此郵件是垃圾郵件;如果不在就將其對應的K個點置為1,即可存入維陣列檢索列表中。但缺點是一封正常郵件通過K個雜湊函式對映成的維陣列的K個點有很小的可能剛好跟一封垃圾郵件相對應,此時就會將一封正常郵件識別為垃圾郵件,但好在這種誤識別率很低,通常在萬分之一以下。現在,讓我們看看如何用布隆過濾器來檢測一個可疑的電子郵件地址 Y 是否在黑名單中。我們用相同的八個隨機數產生器(F1, F2, ..., F8)對這個地址產生八個資訊指紋 s1,s2,...,s8,然後將這八個指紋對應到布隆過濾器的八個二進位制位,分別是 t1,t2,...,t8。如果 Y 在黑名單中,顯然,t1,t2,..,t8 對應的八個二進位制一定是一。這樣在遇到任何在黑名單中的電子郵件地址,我們都能準確地發現。
布隆過濾器決不會漏掉任何一個在黑名單中的可疑地址。但是,它有一條不足之處。也就是它有極小的可能將一個不在黑名單中的電子郵件地址判定為在黑名單中,因為有可能某個好的郵件地址正巧對應個八個都被設定成一的二進位制位。好在這種可能性很小。我們把它稱為誤識概率。在上面的例子中,誤識概率在萬分之一以下。
布隆過濾器的好處在於快速,省空間。但是有一定的誤識別率。常見的補救辦法是在建立一個小的白名單,儲存那些可能別誤判的郵件地址。
優點
相比於其它的資料結構,布隆過濾器在空間和時間方面都有巨大的優勢。布隆過濾器儲存空間和插入/查詢時間都是常數()。另外, 雜湊函式相互之間沒有關係,方便由硬體並行實現。布隆過濾器不需要儲存元素本身,在某些對保密要求非常嚴格的場合有優勢。
布隆過濾器可以表示全集,其它任何資料結構都不能;
k和m相同,使用同一組雜湊函式的兩個布隆過濾器的交併差運算可以使用位操作進行。
缺點
但是布隆過濾器的缺點和優點一樣明顯。誤算率是其中之一。隨著存入的元素數量增加,誤算率隨之增加。但是如果元素數量太少,則使用散列表足矣。
另外,一般情況下不能從布隆過濾器中刪除元素. 我們很容易想到把位陣列變成整數陣列,每插入一個元素相應的計數器加1, 這樣刪除元素時將計數器減掉就可以了。然而要保證安全地刪除元素並非如此簡單。首先我們必須保證刪除的元素的確在布隆過濾器裡面. 這一點單憑這個過濾器是無法保證的。另外計數器迴繞也會造成問題。
在降低誤算率方面,有不少工作,使得出現了很多布隆過濾器的變種。
雜湊函式
雜湊函式(或雜湊演算法,又稱雜湊函式,Hash Function)是一種從任何一種資料中建立小的數字“指紋”的方法。雜湊函式把訊息或資料壓縮成摘要,使得資料量變小,將資料的格式固定下來。該函式將資料打亂混合,重新建立一個叫做雜湊值的指紋。雜湊值通常用來代表一個短的隨機字母和數字組成的字串。好的雜湊函式在輸入域中很少出現雜湊衝突。在散列表和資料處理中,不抑制衝突來區別資料,會使得資料庫記錄更難找到。
雜湊函式的工作原理雜湊函式的性質
所有雜湊函式都有如下一個基本特性:如果兩個雜湊值是不相同的(根據同一函式),那麼這兩個雜湊值的原始輸入也是不相同的。這個特性是雜湊函式具有確定性的結果,具有這種性質的雜湊函式稱為單向雜湊函式。但另一方面,雜湊函式的輸入和輸出不是唯一對應關係的,如果兩個雜湊值相同,兩個輸入值很可能是相同的。但也可能不同,這種情況稱為“雜湊碰撞”,這通常是兩個不同長度的輸入值,刻意計算出相同的輸出值。輸入一些資料計算出雜湊值,然後部分改變輸入值,一個具有強混淆特性的雜湊函式會產生一個完全不同的雜湊值。
典型的雜湊函式都有無限定義域,比如任意長度的位元組字串,和有限的值域,比如固定長度的位元串。在某些情況下,雜湊函式可以設計成具有相同大小的定義域和值域間的一一對應。一一對應的雜湊函式也稱為排列。可逆性可以通過使用一系列的對於輸入值的可逆“混合”運算而得到。
雜湊函式的應用
由於雜湊函式的應用的多樣性,它們經常是專為某一應用而設計的。例如,加密雜湊函式假設存在一個要找到具有相同雜湊值的原始輸入的敵人。一個設計優秀的加密雜湊函式是一個“單向”操作:對於給定的雜湊值,沒有實用的方法可以計算出一個原始輸入,也就是說很難偽造。為加密雜湊為目的設計的函式,如MD5,被廣泛的用作檢驗雜湊函式。這樣軟體下載的時候,就會對照驗證程式碼之後才下載正確的檔案部分。此程式碼有可能因為環境因素的變化,如機器配置或者IP地址的改變而有變動。以保證原始檔的安全性。
錯誤監測和修復函式主要用於辨別資料被隨機的過程所擾亂的事例。當雜湊函式被用於校驗和的時候,可以用相對較短的雜湊值來驗證任意長度的資料是否被更改過。
加密雜湊函式
一個典型的加密單向函式是“非對稱”的,並且由一個高效的雜湊函式構成;一個典型的加密暗門函式是“對稱”的,並且由一個高效的隨機函式構成。
確保傳遞真實的資訊
訊息或資料的接受者確認訊息是否被篡改的性質叫資料的真實性,也稱為完整性。發信人通過將原訊息和雜湊值一起傳送,可以保證真實性。
散列表
散列表是雜湊函式的一個主要應用,使用散列表能夠快速的按照關鍵字查詢資料記錄。(注意:關鍵字不是像在加密中所使用的那樣是祕密的,但它們都是用來“解鎖”或者訪問資料的。)例如,在英語字典中的關鍵字是英文單詞,和它們相關的記錄包含這些單詞的定義。在這種情況下,雜湊函式必須把按照字母順序排列的字串對映到為散列表的內部陣列所建立的索引上。
散列表雜湊函式的幾乎不可能/不切實際的理想是把每個關鍵字對映到唯一的索引上(參考完美雜湊),因為這樣能夠保證直接訪問表中的每一個數據。
一個好的雜湊函式(包括大多數加密雜湊函式)具有均勻的真正隨機輸出,因而平均只需要一兩次探測(依賴於裝填因子)就能找到目標。同樣重要的是,隨機雜湊函式不太會出現非常高的衝突率。但是,少量的可以估計的衝突在實際狀況下是不可避免的(參考生日悖論或鴿洞原理)。
在很多情況下,heuristic雜湊函式所產生的衝突比隨機雜湊函式少的多。Heuristic函式利用了相似關鍵字的相似性。例如,可以設計一個heuristic函式使得像FILE0000.CHK, FILE0001.CHK, FILE0002.CHK,等等這樣的檔名對映到表的連續指標上,也就是說這樣的序列不會發生衝突。相比之下,對於一組好的關鍵字效能出色的隨機雜湊函式,對於一組壞的關鍵字經常效能很差,這種壞的關鍵字會自然產生而不僅僅在攻擊中才出現。效能不佳的雜湊函式表意味著查詢操作會退化為費時的線性搜尋。
錯誤校正與檢測
使用一個雜湊函式可以很直觀的檢測出資料在傳輸時發生的錯誤。在資料的傳送方,對將要傳送的資料應用雜湊函式,並將計算的結果同原始資料一同傳送。在資料的接收方,同樣的雜湊函式被再一次應用到接收到的資料上,如果兩次雜湊函式計算出來的結果不一致,那麼就說明資料在傳輸的過程中某些地方有錯誤了。這就叫做冗餘校驗。
對於錯誤校正,假設相似擾動的分佈接近最小(a distribution of likely perturbations is assumed at least approximately)。 對於一個資訊串的微擾可以被分為兩類,大的(不可能的)錯誤和小的(可能的)錯誤。我們對於第二類錯誤重新定義如下,假如給定H(x)和x+s,那麼只要s足夠小,我們就能有效的計算出x。那樣的雜湊函式被稱作錯誤校正編碼。這些錯誤校正編碼有兩個重要的分類:迴圈冗餘校驗和裡德-所羅門碼。
語音識別
對於像從一個已知列表中匹配一個MP3檔案這樣的應用,一種可能的方案是使用傳統的雜湊函式——例如MD5,但是這種方案會對時間平移、CD讀取錯誤、不同的音訊壓縮演算法或者音量調整的實現機制等情況非常敏感。使用一些類似於MD5的方法有利於迅速找到那些嚴格相同(從音訊檔案的二進位制資料來看)的音訊檔案,但是要找到全部相同(從音訊檔案的內容來看)的音訊檔案就需要使用其他更高階的演算法了。
那些並不緊隨IT工業潮流的人往往能反其道而行之,對於那些微小差異足夠健壯的雜湊函式確實存在。現存的絕大多數雜湊演算法都是不夠健壯的,但是有少數雜湊演算法能夠達到辨別從嘈雜房間裡的揚聲器裡播放出來的音樂的健壯性。有一個實際的例子是Shazam[1] 服務。使用者可以用電話機撥打一個特定的號碼,並將電話機的話筒靠近用於播放音樂的揚聲器。該項服務會分析正在播放的音樂,並將它於儲存在資料庫中的已知的雜湊值進行比較。使用者就能夠收到被識別的音樂的曲名(需要收取一定的費用)。
Rabin-Karp字串搜尋演算法
Rabin-Karp字串搜尋演算法是一個相對快速的字串搜尋演算法,它所需要的平均搜尋時間是O(n).這個演算法是建立在使用雜湊來比較字串的基礎上的。