Hbase 布隆过滤器BloomFilter介绍

1、主要功能

提高随机读的性能

2、存储开销

bloom filter的数据存在StoreFile的meta中,一旦写入无法更新,因为StoreFile是不可变的。Bloomfilter是一个列族(cf)级别的配置属性,如果你在表中设置了Bloomfilter,那么HBase会在生成StoreFile时包含一份bloomfilter结构的数据,称其为MetaBlock;MetaBlock与DataBlock(真实的KeyValue数据)一起由LRUBlockCache维护。所以,开启bloomfilter会有一定的存储及内存cache开销。

3、控制粒度

a)ROW

根据KeyValue中的row来过滤storefile

举例:假设有2个storefile文件sf1和sf2,

sf1包含kv1(r1 cf:q1 v)、kv2(r2 cf:q1 v)

sf2包含kv3(r3 cf:q1 v)、kv4(r4 cf:q1 v)

如果设置了CF属性中的bloomfilter为ROW,那么get(r1)时就会过滤sf2,get(r3)就会过滤sf1

b)ROWCOL

根据KeyValue中的row+qualifier来过滤storefile

举例:假设有2个storefile文件sf1和sf2,

sf1包含kv1(r1 cf:q1 v)、kv2(r2 cf:q1 v)

sf2包含kv3(r1 cf:q2 v)、kv4(r2 cf:q2 v)

如果设置了CF属性中的bloomfilter为ROW,无论get(r1,q1)还是get(r1,q2),都会读取sf1+sf2;而如果设置了CF属性中的bloomfilter为ROWCOL,那么get(r1,q1)就会过滤sf2,get(r1,q2)就会过滤sf1

4、常用场景

1、根据key随机读时,在StoreFile级别进行过滤

2、读数据时,会查询到大量不存在的key,也可用于高效判断key是否存在

5、举例说明

假设x、y、z三个key存在于table中,W不存在

使用Bloom Filter可以帮助我们减少为了判断key是否存在而去做Scan操作的次数

step1)分别对x、y、z运算hash函数取得bit mask,,写到Bloom Filter结构中

step2)对W运算hash函数,从Bloom Filter查找bit mask

如果不存在:三个Bit位至少有一个为0,W肯定不存在该(Bloom Filter不会漏判)

如果存在 :三个Bit位全部全部等于1,路由到负责W的Region执行scan,确认是否真的存在(Bloom Filter有极小的概率误判)

6、源码解析

1.get操作会enable bloomfilter帮助剔除掉不会用到的Storefile

在scan初始化时(get会包装为scan)对于每个storefile会做shouldSeek的检查,如果返回false,则表明该storefile里没有要找的内容,直接跳过

if (memOnly == false&& ((StoreFileScanner) kvs).shouldSeek(scan, columns)) {scanners.add(kvs); }

shouldSeek方法:如果是scan直接返回true表明不能跳过,然后根据bloomfilter类型检查。

if (!scan.isGetScan()) {return true; } byte[] row = scan.getStartRow(); switch (this.bloomFilterType) {case ROW:return passesBloomFilter(row, 0, row.length, null, 0, 0);case ROWCOL:if (columns != null && columns.size() == 1) {byte[] column = columns.first();return passesBloomFilter(row, 0, row.length, column, 0, column.length);}// For multi-column queries the Bloom filter is checked from the// seekExact operation.return true;default:return true;}

2.指明qualified的scan在配了rowcol的情况下会剔除不会用掉的StoreFile。

对指明了qualify的scan或者get进行检查:seekExactly

// Seek all scanners to the start of the Row (or if the exact matching row // key does not exist, then to the start of the next matching Row). if (matcher.isExactColumnQuery()) {for (KeyValueScanner scanner : scanners)scanner.seekExactly(matcher.getStartKey(), false); } else {for (KeyValueScanner scanner : scanners)scanner.seek(matcher.getStartKey()); }

如果bloomfilter没命中,则创建一个很大的假的keyvalue,表明该storefile不需要实际的scan

public boolean seekExactly(KeyValue kv, boolean forward)throws IOException {if (reader.getBloomFilterType() != StoreFile.BloomType.ROWCOL ||kv.getRowLength() == 0 || kv.getQualifierLength() == 0) {return forward ? reseek(kv) : seek(kv);}boolean isInBloom = reader.passesBloomFilter(kv.getBuffer(),kv.getRowOffset(), kv.getRowLength(), kv.getBuffer(),kv.getQualifierOffset(), kv.getQualifierLength());if (isInBloom) {// This row/column might be in this store file. Do a normal seek.return forward ? reseek(kv) : seek(kv);}// Create a fake key/value, so that this scanner only bubbles up to the top// of the KeyValueHeap in StoreScanner after we scanned this row/column in// all other store files. The query matcher will then just skip this fake// key/value and the store scanner will progress to the next column.cur = kv.createLastOnRowCol();return true; }

心中有愿望一定要去闯,努力实现最初的梦想,

Hbase 布隆过滤器BloomFilter介绍

相关文章:

你感兴趣的文章:

标签云: