布隆過濾器

Bloom Filter是HBASE用來優化讀性能的手段,在講解Hbase中Bloom Filter的應用前,咱們先理解下Bloom Filter的原理。web

咱們常常會去判斷一個元素是否在一個集合中,當數據量比較小的時候,咱們能夠用Java的HashSet,Java的HashSet是建立一個散列數組,把原來的元素以某種規則映射到散列數組中特定的位置。但若是咱們須要判斷的元素個數很是大,會致使散列數組很是大,這個時候Bloom Filter就能夠發揮做用。問題引出來了,就是咱們要用盡量小的空間,在大數據場景下實現過濾。接下來我會從做用、算法原理、問題、公式推導、hbase應用來介紹Bloom Filter。算法

做用

Bloom Filter的做用就是過濾。Bloom Filter過濾掉的數據,必定不在集合中;未被過濾的數據可能在集合中,也可能不在。數組

算法流程

  1. 首先須要k個hash函數,每一個函數能夠把key散列成爲1個整數
  2. 初始化一個長度爲n比特的數組,每一個比特位初始化爲0
  3. 當某個key加入集合時,用k個hash函數計算出k個散列值,並把數組中對應的比特位從0置爲1,若是已是1則不變。
  4. 判斷某個key是否在集合時,用k個hash函數計算出k個散列值,並查詢數組中對應的比特位,若是全部的比特位都是1,認爲在集合中。

下圖展現了Bloom Filter的原理
app

問題

bloom filter 存在兩個問題:
1. Bloom Filter有必定機率False Positive發生,就是會把非集合內的元素誤認爲是集合內的元素。若是圖中有個x1,對k個hash函數,有着和x徹底同樣的散列值,可是x1並不在集合{x,y,z}中,這時候bloom filter就會誤判。
2. 該Bloom Filter沒法刪除元素。假設我要從集合中移去x這個元素,可是圖中第6位的「1」,同時由x和z映射着,一旦刪除,會對z形成影響。svg

接下來咱們分析這兩個問題,它們都是由於Bloom Filter節約空間致使的
1. False Positive是Bloom Filter的根本問題,由於hashSet會保存元素或者引用,若是hash碰撞了,咱們直接比較元素來判斷是否存在。而Bloom Filter並不保存元素或者引用,因此在原理上會出現False Positive的可能性。可是咱們能夠調節相關的參數來下降這種機率。
2. Bloom Filter基礎版沒法執行刪除操做。在算法流程中,咱們會把某個比特位置爲1,可是可能該位已經置爲1了,這樣新的信息就沒被保存。這是由於Bloom Filter用的位數組,每一位只有兩種狀態,「0」和「1」表明「出現過」和「沒出現過」。若是咱們能用一個int來表示出現的次數。添加元素的是,在特定位+1;在刪除某個元素的時候,將特定位-1。函數

公式推導

假設bit數組大小爲m、原始數集大小爲n、哈希函數個數爲k:性能

1.1個散列函數時,接收一個元素時,bit數組中某一位置爲0的機率爲: 1 1 m 大數據

2.k個相互獨立的散列函數,接收一個元素時,位數組中某一位置爲0的機率爲:
( 1 1 m ) k 優化

3.將n元素都輸入布隆過濾器,此時某一位置仍爲0的機率爲: ( 1 1 m ) n k atom

4.某一位置爲1的機率爲: 1 ( 1 1 m ) n k

5.當咱們判斷某個元素是否在集合中,咱們是根據k個標誌位,若是全爲1,則判斷正確: [ 1 ( 1 1 m ) n k ] k

6.由極限定理 lim n ( 1 + 1 n ) n = e ,咱們能夠簡化上面的公式

ε [ 1 e n k m ] k

7.對k進行求導,當 k = m n ln 2 ε 取最小,最小值以下

ε m i n l n 2 m n = 0.5 l n 2 m n = 0.62 m n

這個值是理論上true positive和false positive和的最小值,由於是最小值,實際的值確定要偏大一點。可是這裏同時包含了兩項,若是咱們關注false positive的話,確定又要小一點。

若是關注過濾掉的百分比,理論上就是 1 0.62 m n ,取m=10n, 1 0.62 10 = 99.2 ,能夠過濾掉99.2%的數據,只保留0.8%的數據進一步操做。

Bloom Filter在Hbase的做用

1.HBase主要利用BloomFilter來提升隨機讀(Get)的性能

2.對於順序讀(Scan)而言,只有設置了bloomfilter爲ROWCOL且指定Scan的qualifer的纔有優化;若是沒指定qualifer,則沒有優化。

BloomFilter在HBase中的性能

HBASE默認bloom filter級別爲row,在實際使用時,若是須要過濾列,能夠指定ROWCOL。通常能比不開啓bloom filter快三四倍。

BloomFilter在HBase中的開銷

BloomFilter是一個列族級別的配置屬性,若是在表中設置了BloomFilter,那麼HBase會在生成StoreFile時,包含一份BloomFilter 結構的數據,稱其爲MetaBlock(講LRU的時候提到過);MetaBlock與DataBlock一塊兒由LRUBlockCache維護,因此開啓BloomFilter會有較小的的存儲及內存cache開銷。