1. 程式人生 > >過濾器系列(二)—— Cuckoo filter

過濾器系列(二)—— Cuckoo filter

這一篇講的是布穀過濾器(cuckoo fliter),這個名字來源於更早發表的布穀雜湊(cuckoo hash),儘管我也不知道為什麼當初要給這種散列表起個鳥名=_=

由於布穀過濾器本身的思想就源自於布穀雜湊,那麼我們就從布穀雜湊開始說它的設計思想。產生布谷散列表的一個重要背景是人們對於球盒問題的分析:給定N個球,隨機的放在N個盒子裡,在裝球最多的盒子裡,球的個數的期望是多少?答案是\(\Theta (logN/loglogN)\),這個問題其實就是散列表裝填因子為1時的情況分析。後來有一天,人們發現:每次放球的時候,如果隨機選擇兩個盒子,將球放到當時較空的那個盒子裡,那麼這個期望就變成了\(\Theta (loglogN)\)

,這個界小於之前的界,這給了布穀散列表作者啟發。

一個布穀散列表通常有兩張(一般來說)表,分別有一個對應的Hash函式,當有新的項插入的時候,它會計算出這個項在兩張表中對應的兩個位置,這個項一定會被存在這兩個位置之一,而具體是哪一個卻不確定。

下圖是一個布穀散列表的初始化示意圖:

image

現在我們假設有一些項要存入散列表,其每個項都有其對應的兩個位置,先插入第一項A

image

由於插入A的時候其兩個候選位置(0,2)都沒有佔用,所以選擇第一張表或者是第二張表都可以,我們在這裡預設先選擇第一張表,然後插入第二項B
image

我們看到原來的A的位置被B佔用,而A被“踢”到它的備選位置表二的2號位置上了,這就是當發生位置衝突時,布穀散列表的處理邏輯,後來的資料項將會把之前佔用的項踢到另一個位置上。我們接下來插入第三項C

image
沒有衝突,順利搞定,接著插入D

image
D成功的把C踢走了,其實看到這裡讀者應該在猜想,會不會有一種情況,即被踢走的資料的另一個備選位置也被佔用了,這樣怎麼辦?答案是繼續踢,一個踢一個,直到大家都找到自己合適的歸宿為止。那麼如果發現出現了迴圈怎麼辦?答案是GG,這代表布穀散列表走到了極限

image
插入E

image
這裡就發生了多次替換的情況,F代替了E,E代替了A,A代替了B,B找到了空餘的位子

讀者可以考慮一下,如果這個時候要想插入一個“G”,其備選位置是1,2,這樣的話會出現什麼情況?

好了,布穀散列表大概介紹完了,現在該布穀過濾器了。布穀過濾器的主要也是通過布穀雜湊來實現的,其主要變化是:
1.我們不將原來的資料完整的存進來,作為過濾器,當然要省點空間,選用的辦法設計一個指紋,將比較大的原資料變成了一個個指紋串,這樣就大大節省了空間。
2.由於第一點所說,儲存的不是原資料,那麼在替換位置的時候,我們需要再次計算原來的資料的備選位置,這樣一來布穀散列表的方法就失效了。在這裡,作者設計了一個方法,他將兩個Hash函式變成了一個Hash函式,第一張表的備選位置是Hash(x),第二張表的備選位置是\(Hash(x) \oplus hash(fingerprint(x))\)

,即第一張表的位置與儲存的指紋的Hash值做異或運算。這樣做的優點就是不用再另外儲存元素的備選位置,在替換時,可以直接用異或來計算出其另一個備選位置。(讀者可以想想如何通過表二的位置計算出元素在表一中的位置)
3.插入時,優先選擇空位置,而不是儘可能的踢走其他元素。

插入虛擬碼如下:

Algorithm 1: Insert(x)

f = fingerprint(x)
i1 = hash(x)
i2 = i1 xor hash(f)
if bucket[i1] or bucket[i2] has an empty entry then
    //只要有空位就先插入空位裡
    add f to that bucket
    return Done
i  = randomly pick i1 or i2
for n=0;n<MaxNumKicks;++n
    randomly select an entry e from bucket[i];
    swap f and the fingerprint stored in entry e;
    i = i xor hash(f)
    if bucket[i] has an empty entry then
        add f to bucket[i]
        return Done
return Failure // 已經出現迴圈情況了

查詢虛擬碼如下:

Algorithm 2: Lookup(x)
f = fingerprint(x)
i1 = hash(x)
i2 = i1 xor hash(f)
if bucket[i1] or bucket[i2] has f then
    return True
return False

刪除虛擬碼如下:

Algorithm 3: Delete(x)

f = fingerprint(x)
i1 = hash(x)
i2 = i1 xor hash(f)
if bucket[i1] or bucket[i2] has f then
    remove a copy of f from this bucket
return False

刪除這部分值得注意,當被刪除元素的另一個備選位置有其他元素的指紋的時候,我們不能確定到底哪一個是要刪除的元素,其實我們也不去關心到底是不是要刪除的元素,我們直接刪除掉其中的一個。這樣一來,我們其實並沒有真正的刪除掉元素,為什麼這麼說,因為當你刪除掉這個元素的時候我們再查詢這個元素,按照演算法來看我們還是一樣能檢索出來這個元素在我們的布穀過濾器裡,這就是假陽率的其中一個來源(還有一個重要來源是指紋構造的重複,即多個元素產生相同指紋)

下面我們來分析一下布穀過濾器的平均每個元素佔用的位元數,設每個桶裡裝\(b\)個指紋,要求錯誤率的上界為\(\epsilon\)\(f\)為指紋長度。

錯誤率的上界 = \(1-(1-1/2^f)^{2b} \approx 2b/2^f\)
那麼這個上界要求小於要求的上界,即\(2b/2^f \le \epsilon\),得到
\(f \ge log_2^{2b/\epsilon} = log_2^{1/\epsilon} + log_2^{2b}\)
則平均每個元素佔用的位元數為\(C \le (log_2^{1/\epsilon} + log_2^{2b}) / \alpha\)

在原論文中,作者其實後面還做了一個比較強行的優化,在此不提,後面設計其他過濾器的作者也沒有把這個優化算數。。。。不過作者提到了在實際測試中,他們發現當b=4的時候是空間效能最好的情況,所以一般說來,我們直接把b當做常數4,代入到前面算出來的公式中,\(C \le (log_2^{1/\epsilon} + 3) / \alpha\)

布穀過濾器就說到這,布穀過濾器在錯誤率小於3%的時候空間效能是優於布隆過濾器的,而這個條件在實際應用中常常滿足,所以一般來說它的空間效能是要優於布隆過濾器的。而且,布穀過濾器按照普通設計,只有兩個桶,在查詢的時候可以確保兩次訪存就可以做完,相比於布隆過濾器的K個Hash函式K次訪存,在資料量很大不能全部裝載在記憶體中的情況下,多一次訪存那麼時間上就輸了。不過說完優點,布穀過濾器也有其相應的缺點,當裝填因子較高的時候,容易出現迴圈的問題,即插入失敗的情況,到這時就很難辦。另外,它還有跟布隆過濾器共有的一個缺點,就是訪問空間地址不連續,通常可以認為是隨機的,這樣嚴重破壞了程式區域性性,對於Cache流水線來說非常不利,這為之後的過濾器設計埋下了一個伏筆。

相關推薦

過濾器系列—— Cuckoo filter

這一篇講的是布穀過濾器(cuckoo fliter),這個名字來源於更早發表的布穀雜湊(cuckoo hash),儘管我也不知道為什麼當初要給這種散列表起個鳥名=_= 由於布穀過濾器本身的思想就源自於布穀雜湊,那麼我們就從布穀雜湊開始說它的設計思想。產生布谷散列表的一個重要背景是人們對於球盒問題的分析:給定N

過濾器系列—— Bloom filter

因為要做過濾器相關內容,最近讀了一些過濾器方面的文章,準備從中提取主要思想寫幾篇部落格。 作為這系列的第一篇文章,首先得講一下過濾器是幹什麼用的。從歷史發展來看,過濾器最早出現是作為散列表的替代品,那麼功能就要和散列表差不多,主要是查詢當前的元素是否在我已知的集合裡。但是隨著資料量不斷增大,散列表相對來說佔用

雪飲者 決策樹系列決策樹應用

ssi 字符串長度 mes pla 選擇 font com vector nac   本篇以信息增益最大作為最優化策略來詳細介紹決策樹的決策流程。   首先給定數據集,見下圖    註:本數據來源於網絡 本篇將以這些數據作為訓練數據(雖然少,但足以介紹清楚原理!),下圖是決

數據結構系列算法

nal log 如何 空間復雜度 計算 youdao 最好 時間 bsp 高斯求和 計算1+2+...+100 算法的概念就不多說了 強調一點就是,沒有通用的算法,就像永遠沒有銀彈,所有的算法都有自己的適用領域 評判算法好壞的方法 復雜度用大O表示,又分為時間復雜度

【原創】源碼角度分析Android的消息機制系列——ThreadLocal的工作過程

機制 simple hand 這就是 數據存儲 read etc lena 並且 ι 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 在上一篇文章中,我們已經提到了ThreadLocal,它並非線程,而是在線程中存儲數據用的。數據存儲以後,只能在指定的線程中獲取到數據

MySQL系列

sql read 註意 出現 back 總結 lba 區別 不同 MySql 事務 目錄 MySQL系列(一):基礎知識大總結 MySQL系列(二):MySQL事務 MySQL系列(三):索引 什麽是事務(transaction) 保證成批操作要麽完全執行,要麽完全不

Linux系統運維常見面試簡答題系列14題

local 企業 nginx服務 簡答題 ip協議 php out gin 報錯 1. /var/log/messages日誌出現kernel:nf_conntrack:tablefull,dropping packet,請問是什麽原因導致的,如何解決? 此報錯為iptab

Linux VPS/服務器建站系列- 常見的國內雲服務器商家

數據中心 log 中心 相互 網站 能說 之前 體積 選擇 繼續接"Linux VPS/服務器建站系列(一)- 哪些人需要用服務器建站"文章,既然我們開始決定選擇VPS、服務器作為項目用途。在準備實際的操作之前,筆者先準備羅列國內和國外的常見雲服務器商家。因為服務器商家和方

SpringMVC系列: 註解@RequestMapping、@PathVariable

ann handler -- back 聯合 ppi 根目錄 處理方法 ati 一、@RequestMapping 1.@RequestMapping除了能修飾方法,還能修飾類(1)修飾類:提供初步的請求映射信息,相對於web請求的根目錄(2)修飾方法:提供進一步的細分映射

Docker系列鏡像管理

nginx orm lda cast anaconda rip search fff spa 2.1 查看鏡像 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docke

JDBC詳解系列之加載驅動

red mar mys ons try path 替換 host man ---[來自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- ??在JDBC詳解系列(一)之流程中

詳解YUV系列--YUV422

proc 衍生 watermark term fff 本質 image 描述 采樣 hi,各位小夥伴,小編又來了嘍,今天該給大家分享一下YUV422嘍,還是老規矩,老套路哦: 一、文字描述采樣格式:YUV422的采樣格式,簡單理解就是一個2*2的像素塊中,對於4個像素點,采

容器開啟數據服務之旅系列:Kubernetes如何助力Spark大數據分析

容器 控制臺 摘要: 容器開啟數據服務之旅系列(二):Kubernetes如何助力Spark大數據分析 (二):Kubernetes如何助力Spark大數據分析 概述 本文為大家介紹一種容器化的數據服務Spark + OSS on ACK,允許Spark分布式計算節點對阿裏雲OSS對象存儲的直接訪問。

FuelPHP 系列 ------ route 路由

ray align 文件中 數字 eve 區分 creat 內容 ont FuelPHP 中,默認可以通過 /controller_name/function_name 這種方式來訪問,也可以通過自定義路由來訪問。 路由配置在 /fuel/app/config/rout

Java Thread系列線程狀態

做的 tor throws 前臺 bject 線程休眠 enume 死鎖 做出 Java Thread系列(二)線程狀態 一、線程的五種狀態 新建狀態(New):新創建了一個線程對象,尚未啟動。 就緒狀態(Runnable):也叫可運行狀態。線程對象創建後,其他線程調用

Greeplum 系列 安裝部署

dead 元數據 環境搭建 操作 最大數 磁盤 工具 nds md5 Greeplum 系列(二) 安裝部署 本章將介紹如何快速安裝部署 Greenplum,以及 Greenplum 的一些常用命令及工具。本章不會涉及硬件選型、操作系統參數講解、機器性能測試等高級內容,這些

JavaScript夯實基礎系列:閉包

情況 全局環境 賦值 命名 因此 沒有 部分 .com 查詢 ??在JavaScript中函數是一等公民。所謂一等公民是指函數跟其他對象一樣,很普通,可以進行把函數存在數組中、作為參數傳遞、賦值給變量等操作。當函數作為另一個函數的返回值在外部調用時,跟該函數在函數內部調用時

python selenium系列元素定位方式

bdr process sta css_ 講解 term 其他 1.5 win 一 前言元素定位,是操作元素的第一步,也是WebUI自動化的難點和核心。 二 元素定位方法selenium提供了內置的方法完成對待操作元素的定位,主要分為8類,其中,每類又可細分為定位單個元素和

Mybatis學習系列Mapper映射文件

tst 轉換 tin 是個 sql註入 eas 屬性。 object spl Mapper映射文件,作用是用來配置SQL映射語句,根據不同的SQL語句性質,使用不同的標簽,mapper文件中常用的標簽有<iselect>、<insert>、<

HBase 系列安裝部署

clas binary hive .data base start.s 模式 域名 一點 HBase 系列(二)安裝部署 本節以 Hadoop-2.7.6,HBase-1.4.5 為例安裝 HBase 環境。HBase 也有三種模式:本地模式、偽分布模式、分布模式。 一、環