1. 程式人生 > >Bloom Filter 與 Cuckoo Filter概念比較及優化

Bloom Filter 與 Cuckoo Filter概念比較及優化

索引的儲存分為有序和無序,前者使用關聯式容器,比如B樹,後者使用雜湊演算法。關聯式容器時間複雜度穩定為O(logN),且支援範圍查詢。而雜湊演算法的查詢,增刪都比較快,為O(1),但是在碰撞嚴重的情況下,雜湊演算法的時間複雜度會退化到O(n),而Bloom Filter 和 Cuckoo Filter 都是雜湊索引結構

Bloom Filter

介紹

  1. 原理:當一個元素被加入集合時,通過K個Hash函式將這些元素對映成一個位圖陣列(點陣圖)中的K個點,把它們置為1。當檢索時,只需要看看這些點是不是都是1就大約知道集合中有沒有這個檢索的元素。如果這些點有任何一個0,那麼被檢索元素一定不在,如果都是1,可能在。

為什麼bloom filter相比普通的可以提高效率?為什麼都是1的時候只能說明可能存在?

使用多個雜湊為什麼可以避免雜湊碰撞

  1. 優點: 不需要儲存key,節省空間;布隆過濾器儲存空間和插入 / 查詢時間都是常數O(k);

  2. 缺陷:存在誤判率。在判斷一個元素是否屬於某個集合時,有可能把不屬於這個集合的元素誤認為會屬於這個集合,因此布隆過濾器在能容忍低錯誤率的應用場合下,通過極少的錯誤來換取儲存空間的極大節省;不能刪除

為什麼會存在誤判率

構建流程

  • 首先初始狀態下,初始一個包含m位的的位陣列,每一位都置為0
  • 為了表達一個S={x1,x2,…,xn}這樣一個n個元素的陣列,使用k個Hash函式,將它們分別對映到[1,m]的範圍中,對於任意一個元素x,第i個雜湊函式對映的位置hi(x)會被置為1.如果一個位置多次被置為1,那麼只有第一次會起作用
  • 在判斷y是否屬於集合S時,對y使用k次雜湊函式,如果所有的hi(y)的位置都是1,那麼就認為y是集合中的元素,否則就認為y不是集合中的元素

錯誤率

​ 當集合S={x1,x2,…,xn}的所有元素都被k個雜湊函式對映到m位的位陣列中時,這個位陣列中某一位還是0的概率是:

p=(11/m)knekn/m

其中1/m表示任意一個雜湊函式選中這一位標1的概率,用1減去1/m即是雜湊一次都沒有被選中這一位的概率,然後把S對映到位陣列中,需要做kn次雜湊,即可寫出上面的公式,這裡使用到近似公式

>limx>(11/x)x=e>

​ 同理,位陣列任意一位為1的概率約為1-e^(-kn/m),而(1-e^(-kn/m))^k其實就是所謂的false positive rate,即k次雜湊都剛好選中1的區域。

最優雜湊函式個數

​ 怎麼確定幾個雜湊函式能讓元素查詢時的錯誤率降到最低?有兩個方面來思考

  • 如果雜湊函式個數多,那麼對於一個不屬於集合的元素進行查詢時得到0的概率就小
  • 如果雜湊函式個數少,那麼位陣列中的0就多

這裡位陣列0多有什麼影響?

設錯誤率為f,由前面已知錯誤率f = (1-e^(-kn/m))=e^(kln(1-e^(-kn/m)),令g = kln(1-e^(-kn/m),則g為最小,錯誤率也取到最小。由於p = e^(-kn/m),則

g=(m/n)ln(p)ln(1p)
通過對稱性法則,可知當p = 1/2時即是k = ln2*(m/n)時,取得最小值。也就是說,要想保持錯誤率低,最好讓位陣列有一半還空著。最小的錯誤率為lnf = (-m/n)*(ln2)^2

而對於位陣列的大小,經過推導,在錯誤率不大於x的情況下,m至少要等於nlog2(1/x)才能表示任意n個元素的集合。並且在雜湊函式的個數取到最優時,要讓錯誤率不超過x,m至少需要取到最小值的1.44倍。

拓展

​ 因為前面提到過如果一個位置多次被置為1,那麼只有第一次會起作用,所以不支援刪除一個已經插入的關鍵字,會牽動到其他的關鍵字。可以通過counting bloom filter,用一個counter陣列代替位陣列就可以支援刪除了,但是這樣又會使每個bit空間擴張成一個計數值,空間效率又降低了。

counting bloom filter 的實現方式

應用場景

(1)拼寫檢查,即判斷一個單詞是否存在字典。

(2)垃圾郵件過濾

​ 假設郵件伺服器通過傳送方的郵件域或者IP地址對垃圾郵件進行過濾,那麼就需要判斷當前的郵件域或者IP地址是否處於黑名單之中。如果郵件伺服器的通訊郵件數量非常大(也可以認為資料量級上億),那麼也可以使用Bloom Filter演算法。

(3)加快資料庫查詢過程

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

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

Cuckoo Filter

介紹

  1. 基本原理:每個元素都是兩個,分別對映到兩個位置,一個是記錄的位置,一個是備用位置,備用位置是處理碰撞使用的,其處理碰撞的方法就是把原來佔用位置的這個元素體走,安置到備用位置上,如果備用位置上還有人,再把它踢走,如此反覆,直到被踢的次數達到一個上限,才確認雜湊表已滿,並執行rehash。

  2. 結構特點:從結構上時一個bucket陣列,這裡的bucket可以簡單理解為一個儲存item的key的槽,而對於每個key來說,可以通過兩種hash函式得到兩個待選的bucket。判斷一個key是否存在,只需要判斷這兩個bucket是否存在這個key即可。

  3. 演算法特點:因為在插入過程中可能因為反覆踢出無限迴圈下去,這時就需要進行一次迴圈踢出的限制,超出限制則認為過濾器容量不足,需要進行擴容。另外布穀鳥過濾器在bucket上儲存的是key的指紋,主要是考慮到不同的key長度不定,節約空間。fingerprint 一般由key做hash得來,長度較短,一般為8-12bit,也可根據實際資料量調整。

    這裡的實際資料量怎麼判斷確定

  4. 尋找第二個bucket的方法:由於計算key的儲存位置使用的時key本身的值,而儲存時僅儲存了fingerprint,因此當key被擠出,需要重新找位置時,通過指紋資訊來找到第二個bucket

    h1(x)=hash(x),h2(x)=h1(x)hash(xsfingerprint)
    通過異或來實現,所以
    h(1)=h(2)Hash(xsfingerprint)
    已知當前bucket位置,知道指紋資訊,就可以計算除另一個bucket

相關推薦

Bloom Filter Cuckoo Filter概念比較優化

索引的儲存分為有序和無序,前者使用關聯式容器,比如B樹,後者使用雜湊演算法。關聯式容器時間複雜度穩定為O(logN),且支援範圍查詢。而雜湊演算法的查詢,增刪都比較快,為O(1),但是在碰撞嚴重的情況下,雜湊演算法的時間複雜度會退化到O(n),而Bloom

arp ignore背後的rp filterarp filter

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C#C++資料型別比較結構體轉換

//c++:HANDLE(void *) —- c#:System.IntPtr //c++:Byte(unsigned char) —- c#:Sy

主成分分析因子分析之比較實證分析

是因子分析過程中的初始因子載荷矩陣中的元素, 是第j個公共因子,是第i個原觀測變數的特殊因子。且此處的與的均值都為0,方差都為1。   3. 主成分的各系數,是唯一確定的、正交的。不可以對係數矩陣進行任何的旋轉,且係數大小並不代表原變數與主成分的相關程度;而因子模型的係數矩陣是不唯一的、可以進行旋轉的,且該矩

Bloom filter(布隆過濾器)概念原理

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

PowerDesigner概念模型物理模型相互轉換導出數據字典

microsoft 字典 ros 去掉 相互轉換 右擊 soft designer design 最近公司項目竣工,驗收完成後,把整體平臺的所有文檔都寫清楚,找包發給甲方,由於本人是維護數據庫工作,依上面要求,必須編寫《數據庫設計說明書》裏面格式包含三個部分:概念模型

Web開發中Listener、Filter、Servlet的初始化調用

children tomcat啟動 什麽 lis exceptio try 部分 OS findchild 我們在使用Spring+SpringMVC開發項目中,web.xml中一般的配置如下: 1 <?xml version="1.0" encoding=

Django中利用filtersimple_tag為前端自定義函數的實現方法

但是 col filter 成了 應用程序 註冊 number 獲取 except 前言 Django的模板引擎提供了一般性的功能函數,通過前端可以實現多數的代碼邏輯功能,這裏稱之為一般性,是因為它僅支持大多數常見情況下的函數功能,例如if判斷,ifequal對比返回值等

spring component-scan掃描 context:exclude-filter context:include-filter

spring從2.5版本開始支援註解注入,註解注入可以省去很多的xml配置工作。由於註解是寫入java程式碼中的,所以註解注入會失去一定的靈活性,我們要根據需要來選擇是否啟用註解注入。 我們首先看一個註解注入的實際例子,然後再詳細介紹context:component-scan的使用。 如果

CNN中feature map、卷積核、卷積核個數、filter、channel的概念解釋,以及CNN 學習過程中卷積核更新的理解

feature map、卷積核、卷積核個數、filter、channel的概念解釋 feather map的理解 在cnn的每個卷積層,資料都是以三維形式存在的。你可以把它看成許多個二維圖片疊在一起(像豆腐皮一樣),其中每一個稱為一個feature map。 feather map 是怎

maven resources filter springboot衝突

當使用spring-boot-starter-parent時,maven resources filter將失效,因為spring使用 作 為

多執行緒之Locksynchronized比較使用

   第一:先比較兩者的區別: 類別 synchronized

前端獨立實現模糊查詢--filter()match()

filter()方法和match()方法結合使用可以使前端已獲取資料的情況下獨立實現模糊查詢,不再呼叫後端介面,這種情況適用與查詢次數比較多,且資料比較固定的情況,減少呼叫後端介面一定程度上可以緩解後端壓力。 示例: teacherList = allTeacherList.f

利用FilterSession實現登入使用者可以訪問資源,未登入使用者禁止訪問

案例目標 情景:系統中的某些頁面只有在正常登陸後在可以訪問,使用者請求這些頁面是,需要先檢查Session中有無該使用者的資訊,但是在               所有必要的頁面上加上對session的判斷相當麻煩,

models.TABLE.objects.filter()models.TABLE.objects.get()的區別

今天遇到這個坑了,折騰了好幾個小時,記錄一下。 假如你是向去表中查詢某一個數據,且查詢條件對應欄位的值是unique的,那麼就用models.TABLE.objects.get(條件欄位='值'),使用該方法只會返回一個queryset。 models.TABLE.obj

FilterSession配合的簡單過渡例子

4)Filter與Session配合的簡單過渡例子 馬克-to-win:因為下一個登入例子太難,我先給出一個過度的例子,便於大家理解下一個例子。這裡也有個軼事,當我在做下一個登 錄的例子時,發現一個非常隱晦的bug。那就是,我本應寫成:response.sendRedirect("http: //

ElasticSearch教程——filterquery對比

在文章ElasticSearch教程——Kibana簡單操作ES末尾我們用到了must,should以及must not來進行一個數據搜尋的限制以獲取期望的搜尋結果。實際上在除了上述所說方法外我們還能使用filter進行過濾,以獲取自己想要的結果。 新增測試資料 PU

BOOL型別、int型、float型指標變數如何“零值”如何比較

首先了解“零值”的含義: 題目中要求的是零值比較,而非與0進行比較,在C/C++裡“零值”的範圍很大,可i是0、0.0 、FAiiSE或者g空指標”leiflUagg) BOOL flag與“零值”比較的 if 語句 根據布林型別的語義,零值為“假”(記為FALSE),

java.lang.Void void的比較使用

void關鍵字表示函式沒有返回結果,是java中的一個關鍵字。 java.lang.Void是一種型別。例如給Void引用賦值null。 Void nil = null; 通過Void類的程式碼可以看到,Void型別不可以繼承與例項化。 public final cl

IntentIntent Filter的使用

Intent的用法例項: 1.無引數Activity跳轉 Intent it=new Intent(Activity.Main.this,Activity2.class); startActivity(it); 2.向下一個Activity傳送資料(使用Bund