溫故知新-布隆過濾器的基本原理


摘要

本文介紹了布隆過濾器的基本原理,布隆過濾器有非常多的應用場景,在項目開發、大數據推薦系統都有應用。

基本概念

布隆過濾器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出。它由一個很長的二進制向量和一系列隨機映射函數組成,布隆過濾器可以用於檢索一個元素是否在一個集合中。

  • 優點是空間效率和查詢時間都遠遠超過一般的算法;
  • 缺點是有一定的誤識別率(假正例False positives,即Bloom Filter報告某一元素存在於某集合中,但是實際上該元素並不在集合中)和刪除困難,但是沒有識別錯誤的情形(即假反例False negatives,如果某個元素確實沒有在該集合中,那麼Bloom Filter 是不會報告該元素存在於集合中的,所以不會漏報);

基本原理

如果想判斷一個元素是不是在一個集合裏,一般想到的是將所有元素保存起來,然後通過比較確定。但是隨着集合中元素的增加,需要的存儲空間越來越大,檢索速度也越來越慢。它可以通過一個Hash函數將一個元素映射成一個位陣列(Bit Array)中的一個點。只要看看這個點是不是1就知道可以集合中有沒有它了。這就是布隆過濾器的基本思想。

Hash面臨的問題就是衝突。假設 Hash 函數是良好的,如果位陣列長度爲 m 個點,如果想將衝突率降低到例如 1%, 這個散列表就只能容納 m/100 個元素。解決方法也簡單,就是使用多個 Hash,如果它們有一個說元素不在集合中,那肯定就不在。如果它們都說在,雖然也有一定可能性它們在說謊,不過直覺上判斷這種事情的概率是比較低的。

布隆過濾器的原理是,當一個元素被加入集合時,通過K個散列函數將這個元素映射成一個位數組中的K個點,把它們置爲1。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:如果這些點有任何一個0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過濾器的基本思想。

image-20200611164603625

直觀理解,bloom算法類似一個hash set,用來判斷某個元素(key)是否在某個集合中。和一般的hash set不同的是,這個算法無需存儲key的值,對於每個key,只需要k個比特位,每個存儲一個標誌,用來判斷key是否在集合中。優:布隆過濾器在空間和時間方面都有巨大的優勢,存儲空間和插入/查詢時間都是常數;布隆過濾器不需要存儲元素本身,在某些對保密要求非常嚴格的場合有優勢;缺:誤算率(False Positive)是其中之一。隨着存入的元素數量增加,誤算率隨之增加;很難從布隆過濾器中刪除元素;

算法描述

  • k個hash函數,每個函數可以把key散列成爲1個整數;
  • 初始化時,需要一個長度爲m比特的數組,每個比特位初始化爲0;
  • 某個key加入集合時,用k個hash函數計算出k個散列值,並把數組中對應的比特位置爲1;
  • 判斷某個key是否在集合時,用k個hash函數計算出k個散列值,並查詢數組中對應的比特位;
    • 若其中任一位不爲1,則此元素比不在集合中(因爲如果在,則在add時已經把對應的k個bits位置爲1);
    • 同理所有的比特位都是1,認爲在集合中;

誤判概率的證明和計算

p 錯誤概率,m 爲bit大小 ,n爲需要判斷的數據量,k爲每次需要取bit位的次數)

假設布隆過濾器中的hash function滿足假設:若m爲bit數,每個元素都等概率地hash到m個位置中的任何一個,與其它元素被hash到哪個位置無關,則對某一特定bit位在一個元素由某特定hash function插入時沒有被置位爲1的概率爲:

image-20200611164717910

則 k 個hash function中 沒有一個對其置位 的概率爲:

image-20200611164736162

如果插入了n個元素,但都未將其置位 的概率爲:

image-20200611164751335

則此位 被置位的概率爲:

image-20200611164806289

現在考慮query階段,若對應某個待query元素的k bits全部置位爲1,則可判定其在集合中。因此將某元素誤判的概率爲:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pAbbmNjS-1591866259573)(https://wiki.ztjy61.com/download/attachments/15145295/5.png?version=1&modificationDate=1560408415000&api=v2)]

由於

image-20200611164820322

,並且

image-20200611164954000

當m很大時趨近於0,所以

image-20200611164940866

現在計算對於給定的m和n,k爲何值時可以使得誤判率最低。設誤判率爲k的函數爲:

image-20200611164846013

image-20200611164857605

, 則簡化爲

image-20200611165008876

,兩邊取對數

image-20200611165024048

兩邊對k求導

image-20200611165035777

下面求最值

image-20200611165119374

因此,即當

image-20200611165143121

時誤判率最低, (k的公式)此時誤判率爲:

image-20200611165157867

設計和應用布隆過濾器的方法

  • 首先要先由用戶決定要add的元素數n和希望的誤差率P(fpp)。這也是一個設計完整的布隆過濾器需要用戶輸入的僅有的兩個參數,之後的所有參數將由系統計算,並由此建立布隆過濾器。
  • 系統計算需要的內存大小M bits:

image-20200611165223074

  • 再由m,n得到hash function的個數 k

image-20200611165234790

  • add n個元素至布隆過濾器中,再進行query。根據公式,當k最優時:

image-20200611165250417

  • 因此可驗證當P=1%時,存儲每個元素需要9.6 bits:

image-20200611165306307

  • 而每當想將誤判率降低爲原來的1/10,則存儲每個元素需要增加4.8 bits:

    image-20200611165318159

  • 9.6 bits/element不僅包含了被置爲1的k位,還把包含了沒有被置爲1的一些位數。6.72bits 纔是每個元素對應的爲1的bit位數。

    image-20200611165331992

  • 從而使得P(error)最小時:

image-20200611165350053

  • 此概率爲某bit位在插入n個元素後未被置位的概率。因此,想保持錯誤率低,布隆過濾器的空間使用率需爲50%

    image-20200611170016218

典型應用場景

  • 黑名單:比如郵件黑名單過濾器,判斷郵件地址是否在黑名單中;
  • 網絡爬蟲:判斷某個URL是否已經被爬取過;
  • K-V系統快速判斷某個key是否存在:典型的例子有Hbase,Hbase的每個Region中都包含一個BloomFilter,用於在查詢時快速判斷某個key在該region中是否存在,如果不存在,直接返回,節省掉後續的查詢。
  • 搜索引擎中的海量網頁去重;
  • leveldb等數據庫中快速判斷元素是否存在,可以顯著減少磁盤訪問;

參考閱讀

https://www.cnblogs.com/umpjls/p/7319954.html

https://blog.csdn.net/likaiwalkman/article/details/54310757


你的鼓勵也是我創作的動力

打賞地址

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