Bloom Filter簡述

1.適用場景

在極大的數據集合中快速查找某個元素是否存在,但是不要求100%正確.這個是文縐縐的說法,說人話: 一個很理想的場景:分佈式緩存

緩存的數據可能很大,QPS也相當的高,比如千萬級,那麼一般這個緩存集羣就會達到近百臺機器的規模.能不能少點機器呢? 畢竟找老闆要這麼多機器,不容易啊,動不動就是KPI導向!

這個時候Bloom Filter就可以上場了

2.橫向對比

爲了查找某元素是否出現,一般有哪些方法呢?

  • 將所有的數據存起來(比如存數據庫),然後直接查詢唄: 第一是存不下,第二是找不快
  • 使用Hash結構存儲:更加存不下,一般hash空間利用率<=50%, 數據量大了,Hash碰撞也不容小覷
  • 將原始數據md5或者SHA-1,再存hash:MD5結果128Bit, SHA-1結果160Bit,確實比上面的靠譜多了
  • 位向量(將數據哈希值對應的bit位置1):可查證數據顯示,要降低衝突發生的概率到1%,就要將BitSet的長度設置爲數據總數量的100倍

以上方法都是能百分百準確找到或者找不到元素,空間上多少不盡如人意,但是能百分百準確!可是作爲一個緩存服務器,百分百的準確性,有必要麼? 爲了百分百的準確,多花了多少存儲啊!緩存命不中,又不懷孕,是吧? 如果降低5%的準確率,能省20%甚至40%的機器呢?是不是更划算!

3.Bloom Filter原理

布隆過濾器首先是基於上面的方法4,位向量,判斷數據的哈希值對應的bit是否爲1

改進點在於,使用多個哈希函數,而不是一個

比如數據aaa
index1=func_hash_1(aaa)

index2=func_hash_2(aaa)
那麼同時判斷bitset[index1]bitset[index2]是否同時爲1,就能大致知道aaa是否存在.

判斷規則:

  • 只要bitset[index1]活着bitset[index2]任意一個爲0,表示數據aaa不存在
  • bitset[index1],bitset[index2]全部同時爲1,數據aaa可能存在
    爲什麼所有的都是1了,只是可能存在呢?仔細想想,每個數據都會被映射到2個標誌位,可能剛好index1標誌位與bbb的其中一個碰撞(重疊),剛好index2標誌位與ccc的其中一個標誌位碰撞(重疊).
    再直白一點 A=func1(aaa),  B=func2(aaa),  C=func1(bbb),  D=func2(bbb),AB是數據aaa產生的兩個標誌位,CD是數據bbb產生的兩個標誌位.然而很可能aaabbb原始數據都不存在,而是A=func2(ccc),  B=func1(ddd),  C=func2(eee),  D=func1(fff),意思是ccc,ddd,eee,fff分別有一個標誌位與aaa,bbb碰撞(重疊),其實aaa,bbb壓根不存在

4.Counting Bloom Filter

上面已經舉例分析,布隆過濾器存在不準確性,可能誤報.誤報率是多少,有興趣額的可以查查,公式就不貼了.

此處另外一個問題,數據一旦寫入集合,就不能刪除,原因同上面:
ccc,eee,fff,ddd能碰撞虛構出aaa,bbb存在的假象; 那麼你刪除ccc,ddd,eee,fff時將ABCD標誌位置0,也就能虛構aaa,bbb不存在的假象,而此時aaa,bbb可能恰好又倒黴催的真實存在

Counting bloomfilter(CBF),這是一種基本Bloom Filter的變體,CBF將基本Bloom Filter每一個Bit改爲一個計數器,出現一個加1,刪除一個減1,此時就支持刪除數據了

5.數學細節

關於錯誤率估算,最優的哈希函數個數,位數組的大小,這幾個值如何計算調優?鄙人數學不精,不推理公式了,有興趣的搜索一把,應有盡有

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