Bloom Filter是HBASE用来优化读性能的手段,在讲解Hbase中Bloom Filter的应用前,咱们先理解下Bloom Filter的原理。web
咱们常常会去判断一个元素是否在一个集合中,当数据量比较小的时候,咱们能够用Java的HashSet,Java的HashSet是建立一个散列数组,把原来的元素以某种规则映射到散列数组中特定的位置。但若是咱们须要判断的元素个数很是大,会致使散列数组很是大,这个时候Bloom Filter就能够发挥做用。问题引出来了,就是咱们要用尽量小的空间,在大数据场景下实现过滤。接下来我会从做用、算法原理、问题、公式推导、hbase应用来介绍Bloom Filter。算法
Bloom Filter的做用就是过滤。Bloom Filter过滤掉的数据,必定不在集合中;未被过滤的数据可能在集合中,也可能不在。数组
下图展现了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的几率为: 大数据
2.k个相互独立的散列函数,接收一个元素时,位数组中某一位置为0的几率为:
优化
3.将n元素都输入布隆过滤器,此时某一位置仍为0的几率为: atom
4.某一位置为1的几率为:
5.当咱们判断某个元素是否在集合中,咱们是根据k个标志位,若是全为1,则判断正确:
6.由极限定理
,咱们能够简化上面的公式
7.对k进行求导,当
,
取最小,最小值以下
这个值是理论上true positive和false positive和的最小值,由于是最小值,实际的值确定要偏大一点。可是这里同时包含了两项,若是咱们关注false positive的话,确定又要小一点。
若是关注过滤掉的百分比,理论上就是 ,取m=10n, ,能够过滤掉99.2%的数据,只保留0.8%的数据进一步操做。
1.HBase主要利用BloomFilter来提升随机读(Get)的性能
2.对于顺序读(Scan)而言,只有设置了bloomfilter为ROWCOL且指定Scan的qualifer的才有优化;若是没指定qualifer,则没有优化。
HBASE默认bloom filter级别为row,在实际使用时,若是须要过滤列,能够指定ROWCOL。通常能比不开启bloom filter快三四倍。
BloomFilter是一个列族级别的配置属性,若是在表中设置了BloomFilter,那么HBase会在生成StoreFile时,包含一份BloomFilter 结构的数据,称其为MetaBlock(讲LRU的时候提到过);MetaBlock与DataBlock一块儿由LRUBlockCache维护,因此开启BloomFilter会有较小的的存储及内存cache开销。