探索C#之布隆過濾器(Bloom filter)

來源:互聯網
上載者:User

標籤:

閱讀目錄:

  1. 背景介紹
  2. 演算法原理
  3. 誤判率
  4. BF改進
  5. 總結
背景介紹

Bloom filter(後面簡稱BF)是Bloom在1970年提出的二進位向量資料結構。通俗來說就是在大資料集合下高效判斷某個成員是否屬於這個集合。BF其優點在於:

  • 插入和查詢複雜度都是O(n)
  • 空間利用率極高。
例子1:

像Yahoo這類的公用郵件服務提供者,總是需要過濾垃圾郵件。 假設有50億個郵件地址,需要儲存過濾的方法有:

  1. 所有郵件地址都儲存到資料庫。
    缺點:每次都需要查詢資料庫,效率低。
  2. 使用Hashtable儲存到記憶體裡,接近O(1)的查詢效率。
    缺點:太占記憶體,假定每個地址需要十六個字元,50億個需要180G記憶體。
  3. 建立位元組,將每個郵件地址用Hash函數映射到位元組中的某一位。
    缺點: 單個Hash函數衝突太高,會發生多個郵件會映射到同一位上。

而使用BF可以最大限度避免上述缺點,使其可以在更小空間上,進行高效插入和查詢。

例子2:

經常使用緩衝的肯定知道,命中率是個永遠的話題。 特別是在分布式緩衝中,每次不命中就意味著一次跨網路通訊的浪費,無故增加快取服務器壓力。使用BF可以在很大程度上提高快取命中率。

演算法原理

BF很合適解決類似上面的問題。 BF和例子1中的第三種方法非常類似了。不同的是,BF對同一個郵件地址使用多個不同的Hash函數,再去映射位元組的中對應位置。

演算法步驟:
  1. 建立長度為m的位元組,全部置為0。
  2. 取出郵件地址集合(m)中的某一個地址(a), 分別使用k個hash函數對a計算。
  3. 將結果分別映射到位元組中,並設定為1。
  4. 其他成員依次處理。

以函數個數k=8來算,50億個郵件地址只需要5G記憶體足夠了,比例子1中方法2節省32倍空間。

當查詢成員a時是否在垃圾郵件集合m中時,使用同樣k個hash函數進行計算,如果k個結果在位元組中的位值都是1,則判斷a屬於m集合中,即a郵件地址屬於垃圾郵件地址集合m(a∈m)。

關於例子2,可以將所有key儲存到本地記憶體中,每次遠程擷取緩衝時,優先在記憶體集合中判斷是否存在。

  1. 存在?去遠程擷取實際緩衝內容。
  2. 不存在?直接返回,無需再去遠程快取服務器判斷。

這樣能極大提高快取命中率,因為BF存在誤判率,所有並不能達到100%(在key的數量級不高時,用其他方法全存下來也可以)。

誤判率

因為BF使用Hash函數來取得成員的特徵(可理解為成員的指紋資訊),並沒有在位元組中儲存集合內的實際資料內容,所以空間利用率極高,但存在個潛在問題,就是查詢某個成員是否屬於集合時,會發生誤判(False positive)。 也就是說,某個成員實際不在集合中,但BF會得出在集中的結論。 所以BF適用於允許發生一定誤判的情境,如例子1、2中少量過濾失敗或去伺服器拿都是可以接受的。

為什麼會有誤判?

假定有一個長度12的位元組,使用3個hash函數,根據演算法導出成員a得出3、7、11位置,並在位元組中設定為1。 另外個成員b根據演算法也計算得出3、7、11,去位元組檢查其位值時,就發現3、7、11都為1是存在的,而實際不存在(1是成員a設定的),此時就發生了誤判現象。

BF會發生誤判,但不會發生漏判(False Negative),即成員實際在集合中,那麼BF一定能判斷出在集合中,因為成員對應的位置都設定為1了。

可控制性

根據其數組長度m、集合大小n、hash函數個數k、誤判率p,簡單得出下:

  1. 其他不變,集合大小n越大,越多位被設定1,誤判率p越大。
  2. 其他不變,數組漲肚m越大,剩餘為0的位越多,誤判率p越小
  3. 其他不變,添加時k越多,位元組越多被設定為1,即會增大誤判率。查詢時k越多,明顯誤判率可能就會越小。

hash函數個數取值公式 k = ln 2 * m/n 。

其他它關係公式見wiki。

BF改進 

基本的BF在使用時有個缺點:無法刪除集合成員a,只能增加其成員並對其查詢。 有一個很容易想到但錯誤的方法是:如果要刪除成員a,那麼先用k個hash函數對其計算,因為a已經是集合成員,那麼其對應的位元組的位置一定被設定為1,所以只要將對應位置重新設定為0即可。   原因就是位元組的位置不但只提供給a使用,也給其他成員使用,一旦設定為0就會影響其他成員的使用。

比如上面中提高快取命中率的例子,不能刪除成員意味著實際緩衝也不能刪除。如果實際緩衝刪除了,而在集合中的資料無法刪除,就會發生漏判現象。 這樣的話就會大大限制BF的使用情境。

計數BF(count bloom filter)

計數BF是對基本BF的改進,使BF可以支援刪除成員。  因為BF的基本單位是1個bit,只能表達2種狀態,即存在、不存在。 如果把基本單位1bit拓展成多個bit,這樣就能增加更多資訊,表達出多種狀態。

計數BF的基本單元由多個bit表示,一般情況為3、4個bit。  這樣在添加時,在數組位置上的數值上加1即可,刪除成員時-1即可。 查詢集合成員時保持不變,只要數值不為0即認為成員是存在的。

計數BF使基本BF有了更多應用情境。 同樣由於用了多個bit來表示,對應數組大小也相應增加,如果用3bit作為基本單位,那麼數組大小對應增加了3倍。

總結

BF是大資料處理的利器,其使用情境非常多:

  • Google的爬蟲重複URL檢測。
  • 黑名單驗證。
  • 例子中的快取命中率,垃圾郵件過濾。
  • 記憶體擋一層,減輕db空查壓力。
  • hbase、LevelDB內部使用。

基本BF的C#實現見 http://bloomfilter.codeplex.com。

參考資料

[1] http://en.wikipedia.org/wiki/Bloom_filter

[2] http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html

探索C#之布隆過濾器(Bloom filter)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.