布隆過濾器的原理及應用

布隆過濾器是1970年由布隆提出的。他其實是一個很長的二進制向量外加一系列的隨機函數函數來組成。

在正式說到布隆過濾器時,我們要先聊這樣一個話題:
在解決工程類問題時,很多問題的回答並不是只有這兩種布爾狀態:
是 or 否
而可能是這兩種狀態:
一定沒有 or 可能有
亦或者可能是這兩種狀態:
一定有 or 可能沒有

針對以上的背景,我們來舉這樣一個例子:
已知:
從火車站打車到機場,12點出發,在不堵車的情況下,耗時約50分鐘
問題1,如果12點打車出發的話,12點10分會到麼?
答:一定不會
問題2,如果12點打車出發的話,12點50會到麼?
答:不一定會
針對於問題1,問題2的回答,對我們來說也是有幫助的,並不是說毫無用處。
比如你要給司機打電話,詢問是否到達機場,12點10分你肯定不會打電話,這樣的問題沒有意義,還可能會影響司機的駕駛,而12點50你可能就會打電話了,因爲這時候大概率是已經到了。
布隆過濾器就是這樣的一種數據結構,他不像set或者map等判定是某樣東西在或者不在,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )而是用來判定某樣東西在集合中:
1,一定不存在
2,可能存在
下面我們來給出一個布隆過濾器的簡單實現:

如上圖
第一步,像hashmap一樣,我們需要準備一個長度爲N的桶
第二步,準備三個hash方法,他們會根據傳入對象的key,計算出一個index值
第三步,根據計算得到的3個index值,將桶上對應的位置的值設置爲1
這樣一個布隆過濾器就算做好了。
如何使用呢?

如圖,我們先對對象A進行hash運算,得出3個index值,更新到桶中

接着我們可能還會添加不同的對象到桶中,像下圖這個樣子:

然後我們依次對要檢測的對象A、B、C 進行hash1(),hash2() ,hash3()的運算,再根據運算結果匹配桶中相應位置的值時候爲1,從而得出下邊這張圖,

比如在桶中,

index:1 (爲1)3(爲1)6(爲0),因此對象B一定不存在

index:1 (爲1)3(爲1)5(爲1),因此A對象可能存在

這樣做對我們實際業務有什麼用呢?換句話說布隆過濾器有什麼應用場景呢?
在回答這個問題之前,我們要首先明確一點,布隆過濾器不是業務數據的緩存,只是一個用來判斷數據不存在性的緩存,
所以我們纔將其稱爲布隆過濾器,而不是布隆緩存。
因此我們可以將其作爲一個後期需要複雜操作的一個前置過濾判斷,如:
1、底層的查詢邏輯非常複雜,而且性能低下,可以通過布隆過濾器先過濾掉一批請求,降低後臺壓力。
2、 白名單安全校驗:如果過濾器中判定不存在的數據可以直接設定爲安全數據,直接進行安全操作,否則纔會近一步的進行安全管控。

如果數據的存在性發生變化,布隆過濾器是否允許對添加過的元素刪除?

傳統的布隆過濾器是不允許刪除的!
原因如下:
1、無法確定元素是否存在,如果是可能存在的結果,此時會導致誤刪。
2、即使真的確定元素是存在的,也無法刪除。因爲不確定對應的value是否也存在其他元素的映射。

(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )
應該如何設置hash函數的個數和布隆過濾器的長度呢?
很顯然,如果布隆過濾器的長度設置的過小的話,很快所有的位置都會爲1, 此時過濾的結果都是可能存在,
模糊結果的概率就會加大。如果設置的過大的話,則大部分空間都是0,此時又浪費了空間。
就像hashmap一樣,一方面要做到不浪費空間,另外一方面要做到儘可能的降低碰撞。
所以我們需要根據hash 的個數,過濾器的長度,可能存在的元素的數量,對模糊結果的概率(誤判率)得出一個估算。
總體的形式如下:
上圖是誤判率的計算公式。
下圖是對應的概率曲線。

k爲hash公式個數,m爲桶數,p爲誤判率的,n代表數據量

這裏還有一些其他方面的問題:

1、布隆過濾器是不是更浪費空間?

並沒有,傳統過濾器的桶是使用bit來存值的,每個槽位只佔用一個1個bit位

2、多個hash之前的計算有重疊怎麼辦,比如hash1和hash2的運算結果相同,這樣就會使碰撞的概率變大?

這裏可以採用每個hash值對應一個單獨的小桶(或大桶的一部分)來存放,去除掉結果重複的影響。

 

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