http://blog.huang-wei.com/2010/11/02/bloom-filter/
Bloom Filter 原理與應用
介紹
Bloom Filter是一種簡單的節省空間的隨機化的資料結構,支援使用者查詢的集合。一般我們使用STL的std::set, stdext::hash_set,std::set是用紅/黑樹狀結構實現的,stdext::hash_set是用桶式雜湊表。上述兩種資料結構,都會需要儲存未經處理資料資訊,當資料量較大時,記憶體就會是個問題。如果應用情境中允許出現一定幾率的誤判,且不需要逆向遍曆集合中的資料時,Bloom Filter是很好的結構。
優點
- 查詢操作十分高效。
- 節省空間的。
- 易於擴充成並行。
- 集合計算方便。
- 代碼實現方便。
- 有誤判的機率,即存在False Position。
- 無法擷取集合中的元素資料。
- 不支援刪除操作。
缺點
- 有誤判的機率,即存在False Position。
- 無法擷取集合中的元素資料。
- 不支援刪除操作。
定義
Bloom Filter是一個有m位的位元組,初始全為0,並有k個各自獨立的雜湊函數。
圖1
添加操作
每個元素,用k個雜湊Function Compute出大小為k的雜湊向量
,將向量裡的每個雜湊值對應的位設定為1。時間複雜度為 ,一般字串雜湊函數的時間複雜度也就是 。
查詢操作
和添加類似,先計算出雜湊向量,如果每個雜湊值對應的位都為1,則該元素存在。時間複雜度與添加操作相同。
樣本
圖2表示m=16,k=2的Bloom Filter, 和 的雜湊值分別為(3, 6)和(10, 3)。
圖2
False Position
如果某元素不在Bloom Filter中,但是它所有雜湊值的位置均被設為1。這種情況就是False Position,也就是誤判。
借用樣本,如下:
圖3
這個問題其實和雜湊表中的衝突是相同的道理,雜湊表中可以使用開散列和閉散列的方法,而Bloom Filter則允許這樣的情況發生,它更關心於誤判的發生機率。
機率
宏觀上,我們能得出以下結論:
| 參數表 |
變數 |
減少 |
增加 |
| 雜湊函數總數 |
K |
l 更少的雜湊值計算 l 增加False Position的機率 |
l 更多的計算 l 位值0減少 |
| Bloom Filter大小 |
M |
l 更少的記憶體 l 增加False Position的機率 |
l 更多的記憶體 l 降低機率 |
| 元素總數 |
N |
l 降低False Position的機率 |
l 增加機率 |
False Position的機率為 。
假設m和n已知,為了最小化False Position,則 。
資料
圖4
擴充Counter Bloom Filter
Bloom Filter有個缺點,就是不支援刪除操作,因為它不知道某一個位從屬於哪些向量。那我們可以給Bloom Filter加上計數器,添加時增加計數器,刪除時減少計數器。
但這樣的Filter需要考慮附加的計數器大小,假如同個元素多次插入的話,計數器位元較少的情況下,就會出現溢出問題。如果對計數器設定上限值的話,會導致Cache Miss,但對某些應用來說,這並不是什麼問題,如Web Sharing。
Compressed Bloom Filter
為了能在伺服器之間更快地通過網路傳輸Bloom Filter,我們有方法能在已完成Bloom Filter之後,得到一些實際參數的情況下進行壓縮。
將元素全部添加入Bloom Filter後,我們能得到真實的空間使用率,用這個值代入公式計算出一個比m小的值,重新構造Bloom Filter,對原先的雜湊值進行求餘處理,在誤判率不變的情況下,使得其記憶體大小更合適。
應用加速查詢
適用於一些key-value儲存系統,當values存在硬碟時,查詢就是件費時的事。
將Storage的資料都插入Filter,在Filter中查詢都不存在時,那就不需要去Storage查詢了。
當False Position出現時,只是會導致一次多餘的Storage查詢。
圖5
l Google的BigTable也使用了Bloom Filter,以減少不存在的行或列在磁碟上的查詢,大大提高了資料庫的查詢操作的效能。
l 在Internet Cache Protocol中的Proxy-Cache很多都是使用Bloom Filter儲存URLs,除了高效的查詢外,還能很方便得傳輸交換Cache資訊。
網路應用
l P2P網路中尋找資源操作,可以對每條網路通路儲存Bloom Filter,當命中時,則選擇該通路訪問。
l 廣播訊息時,可以檢測某個IP是否已發包。
l 檢測廣播訊息包的環路,將Bloom Filter儲存在包裡,每個節點將自己添加入Bloom Filter。
l 資訊隊列管理,使用Counter Bloom Filter管理資訊流量。
垃圾郵件地址過濾
來自於Google黑板報的例子。
像網易,QQ這樣的公眾電子郵件(email)供應商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。
一個辦法就是記錄下那些發垃圾郵件的 email 地址。由於那些寄件者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。
如果用雜湊表,每儲存一億個 email 地址,就需要 1.6GB 的記憶體(用雜湊表實現的具體辦法是將每一個 email 地址對應成一個八位元組的資訊指紋,然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此一個 email 地址需要佔用十六個位元組。一億個地址大約要 1.6GB, 即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB 的記憶體。
而Bloom Filter只需要雜湊表 1/8 到 1/4 的大小就能解決同樣的問題。
Bloom Filter決不會漏掉任何一個在黑名單中的可疑地址。而至於誤判問題,常見的補救辦法是在建立一個小的白名單,儲存那些可能別誤判的郵件地址。
引用
[1] Bloom filter; http://en.wikipedia.org/wiki/Bloom_filter
[2] Summary Cache: A Scalable Wide-Area Web Cache Sharing Protocol;http://pages.cs.wisc.edu/~cao/papers/summary-cache/
[3] Network Applications of Bloom Filters: A Survey;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.127.9672&rep=rep1&type=pdf
[4] An Examination of Bloom Filters and their Applications;http://cs.unc.edu/~fabian/courses/CS600.624/slides/bloomslides.pdf
[5] 數學之美系列二十一 - 布隆過濾器(Bloom Filter);http://www.google.com.hk/ggblog/googlechinablog/2007/07/bloom-filter_7469.html