例項學習Bloom Filter

2021-09-22 12:15:06 字數 1839 閱讀 6863

0. 科普

1. 為什麼需要bloom filter

2. 基本原理

3. 如何設計bloom filter

4. 例項操作

5. 擴充套件

0. 科普

bloom filter是由bloom在2023年提出的一種多雜湊函式對映快速查詢演算法。通常應用在一些需要快速判斷某個元素是否屬於集合,但是並不嚴格要求100%正確的場合。

1. 為什麼需要bloom filter

舉例說明:假設有2000萬個url,現在判斷乙個新的url是否在這2000萬個之中。可以有的思路:

將訪問過的url儲存到資料庫。

用hashset將訪問過的url儲存起來。那只需接近o(1)的代價就可以查到乙個url是否被訪問過了。

url經過md5等單向雜湊後再儲存到hashset或資料庫。

bit-map方法。建立乙個bitset,將每個url經過乙個雜湊函式對映到某一位。

分析

思路1:當資料量很大時,查詢資料庫變得效率底下

思路2:太消耗記憶體,還得把字串全部儲存起來

思路3:字串經過md5處理後有128個bit,比思路2省了很多空間

思路4:乙個字串僅用一位來表示,比思路3還節省空間

當然前提是會出現誤判(雜湊後表示相同),為了繼承這麼好的思路,同時減少誤判的情況,可以來個折衷:乙個雜湊函式生成乙個位,用多個雜湊函式生成多個位來儲存乙個字串。這樣比bit-map多用了些空間,但是減少了誤判率。

2. 基本原理

這樣把大量的字串存起來。查詢時,用同樣的雜湊處理待查串,如果對應的各位上都為1,說明該字串可能在這些字串中,否則一定不在其中。

3. 如何設計bloom filter

如何降低誤判率是關鍵,這需要

直接利用前人的結論:

其中f'是自己期望的誤判率,m是總共開闢的儲存空間位數,n是待儲存字串的個數,k是雜湊函式的個數,f是真正的誤判率。

4. 例項操作

需求:2000萬個已知url,100個待查url

設計

1. 設定誤判率為0.1, n=2000萬,計算

m = n * 1.44 * math.log(1/f)/math.log(2)=287014588

k = 0.693 * m / n= 10

f = (1 - math.exp(-1 * k * n / m)) ** k = 0.00101298781512

雜湊函式的選取看這裡

參考**(c++)

makefile

main.cc

bloomfilter.h

bloomfilter.cc

hash.h

hash.cc

5. 擴充套件

如何刪除儲存陣列中的元素?

思路:把儲存陣列的每乙個元素擴充套件一下(原來是1b)用來儲存該位置被置1的次數。儲存是,計數次數加一;刪除的時候,計數次數減一。

Bloom Filter演算法優化

基於redis的bloom filter去重,利用redis的string資料結構,但redis的string最大只能512m,所以資料過大的時候,需要申請多個去重塊。bloom filter對乙個很長的字串進行雜湊對映時會出錯,常誤判為已經存在,所以我們進行一次壓縮 md5 sha1 將去重佇列和...

Bloom Filter演算法 簡介

bloom filter演算法 其實可以看作 bit map 的一種擴充套件。它把已存在的元素通過多個hash 函式對映到乙個 bit 序列,對於每乙個元素根據hash函式的結果把相應的 位置置一 這個bit序列通常很長,但是比起記住所有元素它占用的空間是小的 在判斷乙個元素時候已存在的時候,它會把...

Bloom Filter 布隆演算法

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