布隆过滤器

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开销。