1. 程式人生 > >Bloom Filters布魯姆過濾器

Bloom Filters布魯姆過濾器

Bloom Filters by Example (連結:http://billmill.org/bloomfilter-tutorial/

以下是關於布魯姆過濾器的知識點 布隆過濾器是一種資料結構,快速和節省記憶體,能用於判定一個元素是否存在於一個集合中。
這種效率的代價是Bloom filter是一種概率資料結構,元素不是絕對的在組裡或可能在組裡。
Bloom filter的基本資料結構是一個位向量。
在以下文字,我們ķ個雜湊值,m位的過濾器,和n已插入的元素來介紹Bloom filter 雜湊函式

Bloom filter應使用的雜湊函式是獨立和均勻分佈的,使雜湊函式執行時儘可能的快。

(而加密雜湊如sha1,儘管被廣泛使用,但不是很好的選擇)。

例子:簡單的雜湊足夠獨立,其中包括murmur, the fnv series of hashes, and Jenkins Hashes.


然而2016年8月31日的更新:Murmur(雜音)似乎被打破了。現在你可能更喜歡SipHash。
在一個快於加密雜湊函式中可以看到區別當開啟一個 bloom filter 從md5到Murmur的實現時,增速提高到了~ 800%。
關於bloom filter的實現有個簡短的調查
Cassandra uses Murmur hashesHadoop includes default implementations of Jenkins and Murmur hashes
Plan9 uses a simple hash as proposed in Mitzenmacher 2005Sdroege Bloom filter uses fnv1a (included just because I wanted to show one that uses fnv.)Squid uses MD5
雙雜湊
注意,您不需要選擇兩個或兩個以上不同的雜湊函式。相反,您可以通過兩雙雜湊函式建立任意數量的新雜湊函式。
給定兩個獨立的雜湊函式a,b和一個value值 x,你可以建立一個新的雜湊雜湊函式:
hashi(x, m) = (hasha(x) + i × hashb
(x)) mod m

How big should Imake my Bloom filter?

能通過誤報修改你Bloom filter的過濾速度,這是一個很好的特性。更大的過濾器將具有更少的誤報,而較小的則誤報會多一點。
誤報率將約為(1-e-kn/m)k,所以你只需按你的期望插入n元素的數量,並嘗試不同的k值和m值,為您的應用程式配置過濾器。
但這導致一個明顯的問題:How many hash functions should I use? 雜湊函式越多,導致過濾器越慢,並且滿的更快。如果過少,可能會有很多誤報。
當你必須選擇ķ來建立過濾器,你必須確定n值大概在什麼範圍,一旦你確定了,你還要確定一個潛在的k(雜湊函式的數量)和一個m(位元)。
這似乎是一個困難的優化問題,但幸運的是,給定一個m和n,有一個函式能選擇最優值k:(m/n)ln(2) 因此,要選擇bloom filter的大小:
  1. 選擇一個大概值n
  2. 選擇一個值m
  3. 計算的最優值ķ
  4. 計算我們所選擇的值的錯誤率nm,和ķ。如果這是不可接受的,回到步驟2和改變m; 否則我們就完成了

How fast and space efficient is a Bloom filter?

如何快速,節省空間

給定一個m位元和k個雜湊函式的bloom filter,複雜度是O(K)。
也就是說,每次想新增一個元素到集合,你只需要在ķ個雜湊函式中執行元素將其新增到集合或檢查所在的位。
空間優勢很難總結,這取決於你願意容忍的錯誤率。這也取決於元素插入的潛在範圍;如果是非常有限的,使用一個確定的位向量會更好。如果你甚至不能大概的估計要插入的元素數量,你最好有一個雜湊表或做一個可伸縮的bloom filter。

參考

1布魯姆過濾器的網路應用程式:調查,布羅德和Mitzenmacher。一個很好的概述。

2:維基百科,這對布魯姆過濾器的出色和全面的網頁

3:少雜湊,同樣的效能,基爾希和Mitzenmacher


(如若有翻譯或者知識錯誤,歡迎留言評論)