1. 程式人生 > >布隆過濾器(Bloom Filter)詳解

布隆過濾器(Bloom Filter)詳解

轉: http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html

布隆過濾器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它實際上是由一個很長的二進位制向量和一系列隨機對映函式組成,布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率(假正例False positives,即Bloom Filter報告某一元素存在於某集合中,但是實際上該元素並不在集合中)和刪除困難,但是沒有識別錯誤的情形(即假反例False negatives,如果某個元素確實沒有在該集合中,那麼Bloom Filter 是不會報告該元素存在於集合中的,所以不會漏報)。

在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷 它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,一個網址是否被訪問過等等。最直接的方法就是將集合中全部的元素存在計算機中,遇到一個新 元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用雜湊表(hash table)來儲存的。它的好處是快速準確,缺點是費儲存空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,雜湊表儲存效率低的問題就顯現出來 了。比如說,一個象 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發垃圾郵件的 email 地址。由於那些傳送者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。如果用雜湊表,每儲存一億 個 email 地址, 就需要 1.6GB 的記憶體(用雜湊表實現的具體辦法是將每一個 email 地址對應成一個八位元組的資訊指紋(詳見:

googlechinablog.com/2006/08/blog-post.html), 然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此一個 email 地址需要佔用十六個位元組。一億個地址大約要 1.6GB, 即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB 的記憶體。除非是超級計算機,一般伺服器是無法儲存的[2]。(該段引用谷歌數學之美:http://www.google.com.hk/ggblog/googlechinablog/2007/07/bloom-filter_7469.html)

基本概念

如果想判斷一個元素是不是在一個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。連結串列,樹等等資料結構都是這種思路. 但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢。不過世界上還有一種叫作散列表

(又叫雜湊表,Hash table)的資料結構。它可以通過一個Hash函式將一個元素對映成一個位陣列(Bit Array)中的一個點。這樣一來,我們只要看看這個點是不是 1 就知道可以集合中有沒有它了。這就是布隆過濾器的基本思想。

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

優點

相比於其它的資料結構,布隆過濾器在空間和時間方面都有巨大的優勢。布隆過濾器儲存空間和插入/查詢時間都是常數。另外, Hash 函式相互之間沒有關係,方便由硬體並行實現。布隆過濾器不需要儲存元素本身,在某些對保密要求非常嚴格的場合有優勢。

布隆過濾器可以表示全集,其它任何資料結構都不能;

k 和 m 相同,使用同一組 Hash 函式的兩個布隆過濾器的交併差運算可以使用位操作進行。

缺點

但是布隆過濾器的缺點和優點一樣明顯。誤算率(False Positive)是其中之一。隨著存入的元素數量增加,誤算率隨之增加。但是如果元素數量太少,則使用散列表足矣。

另外,一般情況下不能從布隆過濾器中刪除元素. 我們很容易想到把位列陣變成整數陣列,每插入一個元素相應的計數器加1, 這樣刪除元素時將計數器減掉就可以了。然而要保證安全的刪除元素並非如此簡單。首先我們必須保證刪除的元素的確在布隆過濾器裡面. 這一點單憑這個過濾器是無法保證的。另外計數器迴繞也會造成問題。

False positives 概率推導

假設 Hash 函式以等概率條件選擇並設定 Bit Array 中的某一位,m 是該位陣列的大小,k 是 Hash 函式的個數,那麼位陣列中某一特定的位在進行元素插入時的 Hash 操作中沒有被置位的概率是:

那麼在所有 k 次 Hash 操作後該位都沒有被置 "1" 的概率是:

如果我們插入了 n 個元素,那麼某一位仍然為 "0" 的概率是:

因而該位為 "1"的概率是:

現在檢測某一元素是否在該集合中。標明某個元素是否在集合中所需的 k 個位置都按照如上的方法設定為 "1",但是該方法可能會使演算法錯誤的認為某一原本不在集合中的元素卻被檢測為在該集合中(False Positives),該概率由以下公式確定:

其實上述結果是在假定由每個 Hash 計算出需要設定的位(bit) 的位置是相互獨立為前提計算出來的,不難看出,隨著 m (位陣列大小)的增加,假正例(False Positives)的概率會下降,同時隨著插入元素個數 n 的增加,False Positives的概率又會上升,對於給定的m,n,如何選擇Hash函式個數 k 由以下公式確定:

此時False Positives的概率為:

而對於給定的False Positives概率 p,如何選擇最優的位陣列大小 m 呢,

上式表明,位陣列的大小最好與插入元素的個數成線性關係,對於給定的 m,n,k,假正例概率最大為:

下圖是布隆過濾器假正例概率 p 與位陣列大小 m 和集合中插入元素個數 n 的關係圖,假定 Hash 函式個數選取最優數目:

Bloom Filter 用例

Google 著名的分散式資料庫 Bigtable 使用了布隆過濾器來查詢不存在的行或列,以減少磁碟查詢的IO次數[3]。

Squid 網頁代理快取伺服器在 cache digests 中使用了也布隆過濾器[4]。

Venti 文件儲存系統也採用布隆過濾器來檢測先前儲存的資料[5]。

SPIN 模型檢測器也使用布隆過濾器在大規模驗證問題時跟蹤可達狀態空間[6]。

Google Chrome瀏覽器使用了布隆過濾器加速安全瀏覽服務[7]。

在很多Key-Value系統中也使用了布隆過濾器來加快查詢過程,如 Hbase,Accumulo,Leveldb,一般而言,Value 儲存在磁碟中,訪問磁碟需要花費大量時間,然而使用布隆過濾器可以快速判斷某個Key對應的Value是否存在,因此可以避免很多不必要的磁碟IO操作,只是引入布隆過濾器會帶來一定的記憶體消耗,下圖是在Key-Value系統中布隆過濾器的典型使用:

布隆過濾器相關擴充套件

 Counting filters

基本的布隆過濾器不支援刪除(Deletion)操作,但是 Counting filters 提供了一種可以不用重新構建布隆過濾器但卻支援元素刪除操作的方法。在Counting filters中原來的位陣列中的每一位由 bit 擴充套件為 n-bit 計數器,實際上,基本的布隆過濾器可以看作是隻有一位的計數器的Counting filters。原來的插入操作也被擴充套件為把 n-bit 的位計數器加1,查詢操作即檢查位陣列非零即可,而刪除操作定義為把位陣列的相應位減1,但是該方法也有位的算術溢位問題,即某一位在多次刪除操作後可能變成負值,所以位陣列大小 m 需要充分大。另外一個問題是Counting filters不具備伸縮性,由於Counting filters不能擴充套件,所以需要儲存的最大的元素個數需要提前知道。否則一旦插入的元素個數超過了位陣列的容量,false positive的發生概率將會急劇增加。當然也有人提出了一種基於 D-left Hash 方法實現支援刪除操作的布隆過濾器,同時空間效率也比Counting filters高。

Data synchronization

Byers等人提出了使用布隆過濾器近似資料同步[9]。

Bloomier filters

Chazelle 等人提出了一個通用的布隆過濾器,該布隆過濾器可以將某一值與每個已經插入的元素關聯起來,並實現了一個關聯陣列Map[10]。與普通的布隆過濾器一樣,Chazelle實現的布隆過濾器也可以達到較低的空間消耗,但同時也會產生false positive,不過,在Bloomier filter中,某 key 如果不在 map 中,false positive在會返回時會被定義出的。該Map 結構不會返回與 key 相關的在 map 中的錯誤的值。

Compact approximators[11]

Stable Bloom filters[12]

Scalable Bloom filters[13]

Attenuated Bloom filters[14]

相關連結

參考資料

[1]維基百科:布隆過濾器:http://zh.wikipedia.org/zh/%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8

[2]數學之美二十一:布隆過濾器(Bloom Filter):http://www.google.com.hk/ggblog/googlechinablog/2007/07/bloom-filter_7469.html

[3]Chang, Fay; Dean, Jeffrey; Ghemawat, Sanjay; Hsieh, Wilson; Wallach, Deborah; Burrows, Mike; Chandra, Tushar; Fikes, Andrew et al. (2006), "Bigtable: A Distributed Storage System for Structured Data"Seventh Symposium on Operating System Design and Implementation

[4]Wessels, Duane (January 2004), "10.7 Cache Digests", Squid: The Definitive Guide (1st ed.), O'Reilly Media, p. 172, ISBN 0-596-00162-2, "Cache Digests are based on a technique first published by Pei Cao, called Summary Cache. The fundamental idea is to use a Bloom filter to represent the cache contents."

[9]Byers, John W.; Considine, Jeffrey; Mitzenmacher, Michael; Rost, Stanislav (2004), "Informed content delivery across adaptive overlay networks", IEEE/ACM Transactions on Networking 12 (5): 767, DOI:10.1109/TNET.2004.836103

[10]Chazelle, Bernard; Kilian, Joe; Rubinfeld, Ronitt; Tal, Ayellet (2004), "The Bloomier filter: an efficient data structure for static support lookup tables"Proceedings of the Fifteenth Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 30–39

[11]Boldi, Paolo; Vigna, Sebastiano (2005), "Mutable strings in Java: design, implementation and lightweight text-search algorithms",Science of Computer Programming 54 (1): 3–23, DOI:10.1016/j.scico.2004.05.003

[12]Deng, Fan; Rafiei, Davood (2006), "Approximately Detecting Duplicates for Streaming Data using Stable Bloom Filters",Proceedings of the ACM SIGMOD Conference, pp. 25–36

[13]Almeida, Paulo; Baquero, Carlos; Preguica, Nuno; Hutchison, David (2007), "Scalable Bloom Filters"Information Processing Letters 101 (6): 255–261, DOI:10.1016/j.ipl.2006.10.007

[14]http://en.wikipedia.org/wiki/Bloom_filter#Attenuated_Bloom_filters


相關推薦

過濾器(Bloom Filter)

轉: http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆過濾器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它實際上是由一個

大量資料去重:Bitmap點陣圖演算法和過濾器(Bloom Filter)

Bitmap演算法 與其說是演算法,不如說是一種緊湊的資料儲存結構。是用記憶體中連續的二進位制位(bit),用於對大量整型資料做去重和查詢。其實如果並非如此大量的資料,有很多排重方案可以使用,典型的就是雜湊表。 實際上,雜湊表為每一個可能出現的數字提供了一個一一對映的關係,每個元素都相當於有

url去重 --過濾器 bloom filter原理及python實現

array art bits bras pos for tar ack setup https://blog.csdn.net/a1368783069/article/details/52137417 # -*- encoding: utf-8 -*- """This

過濾器Bloom Filter演算法的Java實現(用於去重)

在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個 集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,一個網址是否被訪問過等等。最直接的方法就

過濾器-Bloom Filter

/** * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by

分散式快取擊穿(過濾器 Bloom Filter

前面的文章介紹了快取的分類和使用的場景。通常情況下,快取是加速系統響應的一種途徑,通常情況下只有系統的部分資料。當請求了快取中沒有的資料時,這時候就會回源到DB裡面。此時如果黑客故意對上面資料發起大量請求,則DB有可能會掛掉,這就是快取擊穿。當然快取掛掉的

大量資料去重:Bitmap和過濾器(Bloom Filter)

5TB的硬碟上放滿了資料,請寫一個演算法將這些資料進行排重。如果這些資料是一些32bit大小的資料該如何解決?如果是64bit的呢?在面試時遇到的問題,問題的解決方案十分典型,但對於海量資料處理接觸少的同學可能一時也想不到什麼好方案。介紹兩個演算法,對於空間的利用到達了一種極

過濾器(Bloom Filter)

布隆過濾器(Bloom Filter)是一種基於Hash的高效查詢資料結構,它能夠快速答覆“某個元素是否存在”的問題。布隆過濾器只能用於新增元素與查詢元素,不能夠用於刪除元素。 在布隆過濾器之前,使用的是基於Hash的快速查詢演算法。Hash可以將一個元素進行雜湊,然後根據雜湊值對映到陣列的某一個位置。並且

過濾器 Bloom Filter

# 一 前言 假如有一個15億使用者的系統,每天有幾億使用者訪問系統,要如何快速判斷是否為系統中的使用者呢? - 方法一,將15億使用者儲存在資料庫中,每次使用者訪問系統,都到資料庫進行查詢判斷,準確性高,但是查詢速度會比較慢。 - 方法二,將15億使用者快取在Redis記憶體中,每次使用者訪問系統,都到R

海量資料處理之Bloom Filter

一、什麼是Bloom Filter    Bloom Filter是一種空間效率很高的隨機資料結構,它的原理是,當一個元素被加入集合時,通過K個Hash函式將這個元素對映成一個位陣列(Bit array)中的K個點,把它們置為1。檢索時,我們只要看看這些點是不是都是1就(大約

Bloom Filter過濾器

布隆過濾器 數據及結構 原文鏈接:http://blog.csdn.net/qq_38646470/article/details/794316591.概念:如果想判斷一個元素是不是在一個集合裏,一般想到的是將所有元素保存起來,然後通過比較確定。鏈表,樹等等數據結構都是這種思路. 但是隨著集合中元素的

Bloom filter(過濾器)概念與原理

概念 int 復雜 gravity water pac 基數 AS class https://en.wikipedia.org/wiki/Bloom_filter 寫在前面 在大數據與雲計算發展的時代,我們經常會碰到這樣的問題。我們是否能高效的判斷一個用

Bloom Filter(過濾器)

最早看到這個精巧的資料結構是在《數學之美》上,今天梳理一下它的特點。 布隆過濾器:        Bloom Filter是一個節省空間的概率型資料結構,被用來測試一個元素是否存在於集合中。“元素實際不存在於集合中但判定為存在“的這類錯誤(False

過濾器Bloom Filter)(給兩個檔案,分別有100億個字串,我們只要1g的記憶體,如何找到兩個檔案的交集?分別給出精確演算法和近似演算法?)

  給兩個檔案,分別有100億個字串,我們只要1g的記憶體,如何找到兩個檔案的交集?分別給出精確演算法和近似演算法? 精確演算法:   我們可以建立1000個檔案,運用雜湊函式先將檔案1的字串儲存在對應的檔案中,之後再檔案2中取元素,通過雜湊函式計算出雜湊地址

過濾器Bloom Filter)的簡單實現

最近在部署Scrapy專案時,瞭解到Scrapy_Redis的去重機制並不太友好。查詢之後發現了一個更好的去重方式——布隆過濾器。 使用布隆過濾器的原因: 關於布隆過濾器的詳細原理及介紹,推薦一個部落格:https://www.cnblogs.com/haippy/archive/2012/

過濾器Bloom Filter)原理以及應用

布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實際上是一個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。 hash原理

數學之美系列二十一 - 過濾器Bloom Filter

2007年7月3日 上午 09:35:00 在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網

Redis快取擊穿解決辦法之bloom filter過濾器

布隆過濾器:Google Guava類庫原始碼分析及基於Redis Bitmaps的重構 2017/12/30 · 開發 · Bitmaps, BloomFilter, Guava, Redis, 布隆過濾器 本文源地址:http://www.fullstack

過濾器的簡單介紹與例項(Bloom Filter)

布隆在1970年提出了布隆過濾器(Bloom Filter),是一個很長的二進位制向量(可以想象成一個序列)和一系列隨機對映函式(hash function)。  布隆過濾器可以用於檢索一個元素是否在一個集合中。  優點:佔用空間小,查詢快  缺點:有誤判,刪除困難 1

Bloom Filter 過濾器

布隆過濾器在很多場合能發揮很好的效果,比如:網頁URL的去重,垃圾郵件的判別,集合重複元素的判別,查詢加速(比如基於key-value的儲存系統)等,下面舉幾個例子: 有兩個URL集合A,B,每個集合中大約有1億個URL,每個URL佔64位元組,有1G的記憶體,如何找出兩個