Hbase过滤器


目录

  • hbase过滤器
    • 过滤器的参数
    • 操作符
    • 六大比较过滤器
      • BinaryComparator
      • BinaryPrefixComparator
      • NullComparator
      • BitComparator
      • RegexStringComparator
      • SubstringComparator
      • 专用过滤器
        • 单列值过滤器:SingleColumnValueFilter
        • 列值排除过滤器:SingleColumnValueExcludeFilter
        • rowkey前缀过滤器:PrefixFilter
        • 分页过滤器PageFilter
    • Bloom Filter(布隆过滤器)
  • hive整合hbase

hbase过滤器 过滤器可以根据列簇、列、版本等更多条件进行过滤。
hbase三维有序(行键、列、版本有序)
过滤器的参数 使用过滤至少需要需要两类参数:一类是抽象的操作符,一类是比较器。
代码及资源:
https://gitee.com/yu-min-guo/hbase-test
操作符
  • LESS <
  • LESS_OR_EQUAL <=
  • EQUAL =
  • NOT_EQUAL <>
  • GREATER_OR_EQUAL >=
  • GREATER >
  • NO_OP 排除所有
六大比较过滤器 BinaryComparator
按字节索引顺序比较指定字节数组,采用Bytes.compareTo(byte[])
BinaryPrefixComparator
通BinaryComparator,只是比较左端前缀的数据是否相同
NullComparator
判断给定的是否为空
BitComparator
按位比较
RegexStringComparator
提供一个正则的比较器,仅支持 EQUAL 和非EQUAL
SubstringComparator
判断提供的子串是否出现在中
专用过滤器 单列值过滤器:SingleColumnValueFilter
SingleColumnValueFilter会返回满足条件的cell所在行的所有cell的值(即会返回一行数据)
通过SingleColumnValueFilter与查询文科班所有学生信息
@Test /** * SingleColumnValueFilter * 可以指定一个列进行返回 * 该过滤器会将符合过滤条件的列对应的cell所在的整行数据进行返回 * 如果某条数据的列不符合条件,则会将整条数据进行过滤 * 如果数据中不存在指定的列,则默认进行返回 */ public void SingleColumnValueFilterTest() throws IOException { SingleColumnValueFilter scvf = new SingleColumnValueFilter( "cf1".getBytes(), "age".getBytes(), CompareFilter.CompareOp.GREATER, "23".getBytes() ); getFilterResult(scvf); }

列值排除过滤器:SingleColumnValueExcludeFilter
与SingleColumnValueFilter相反,会排除掉指定的列,其他的列全部返回
通过SingleColumnValueExcludeFilter与BinaryComparator查询文科一班所有学生信息,最终不返回clazz列
@Test /** * 过滤文科班的学生 * SingleColumnValueExcludeFilter 单列值排除过滤器、 * 与单列值过滤器最大的区别就是结果包不包含比较的列 * */ public void SingleColumnValueExcludeFilterTest() throws IOException {BinaryPrefixComparator bpc = new BinaryPrefixComparator("文科".getBytes()); SingleColumnValueExcludeFilter scvef = new SingleColumnValueExcludeFilter( "cf1".getBytes(), "clazz".getBytes(), CompareFilter.CompareOp.EQUAL, bpc ); getFilterResult(scvef); }

rowkey前缀过滤器:PrefixFilter
通过PrefixFilter查询以150010008开头的所有前缀的rowkey
@Test /** * 过滤出rowkey以 150010088 开头的学生 * PrefixFilter rowkey前缀过滤器,效率最高 * 相当于上面的比较器+过滤器 */ public void PrefixFilterTest() throws IOException { PrefixFilter prefixFilter = new PrefixFilter("150010088".getBytes()); getFilterResult(prefixFilter); }

分页过滤器PageFilter
通过PageFilter查询第三页的数据,每页10条
使用PageFilter分页效率比较低,每次都需要扫描前面的数据,直到扫描到所需要查的数据
可设计一个合理的rowkey来实现分页需求
@Test /** * 分页过滤器:PageFilter * 获取第四页的数据,每页10条 * * 实际上需要遍历该页前面所有的数据,性能非常低 */ public void PageFilter1() throws IOException { int page = 4; int pageSize = 10; // 首先先获取第4页的第一条数据的rk int page_first = (page - 1) * pageSize + 1; PageFilter pageFilter1 = new PageFilter(page_first); Scan scan = new Scan(); scan.setFilter(pageFilter1); //scan.setLimit(40); // PageFilter就相当于setLimitString rowkey = null; ResultScanner scanner = student.getScanner(scan); for (Result rs : scanner) { rowkey = Bytes.toString(rs.getRow()); }Scan scan1 = new Scan(); scan1.withStartRow(rowkey.getBytes()); PageFilter pageFilter2 = new PageFilter(pageSize); scan1.setFilter(pageFilter2); ResultScanner scanner2 = student.getScanner(scan1); for (Result rs : scanner2) { String id = Bytes.toString(rs.getRow()); String name = Bytes.toString(rs.getValue("info".getBytes(), "name".getBytes())); String age = Bytes.toString(rs.getValue("info".getBytes(), "age".getBytes())); String gender = Bytes.toString(rs.getValue("info".getBytes(), "gender".getBytes())); String clazz = Bytes.toString(rs.getValue("info".getBytes(), "clazz".getBytes())); System.out.println(id + "," + name + "," + age + "," + gender + "," + clazz); }}

Bloom Filter(布隆过滤器)
  • 一个布隆过滤器包含一个二进制向量和n个随机映射函数。
  • 布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
  • 布隆过滤器可以100%确定元素不在集合,但不能100%确定在。
  • 通过BloomFilter快速判断rowkey是否在这个Hfile中,从而过滤掉大部分的Hfile,减少需要扫描的Block。
  • Bloom Filter有两个很重要的参数
    • 哈希函数个数
    • 位数组的大小
HFile 中和 Bloom Filter 相关的Block,
Scanned Block Section(扫描HFile时被读取):Bloom Block
Load-on-open-section(regionServer启动时加载到内存):BloomFilter Meta Block、Bloom Index Block
Bloom Block:Bloom数据块,存储Bloom的位数组
Bloom Index Block:Bloom数据块的索引
BloomFilter Meta Block:从HFile角度看bloom数据块的一些元数据信息,大小个数等等。
【Hbase过滤器】HBase中每个HFile都有对应的位数组,KeyValue在写入HFile时会先经过几个hash函数的映射,映射后将对应的数组位改为1,get请求进来之后再进行hash映射,如果在对应数组位上存在0,说明该get请求查询的数据不在该HFile中。
HFile中的Bloom Block中存储的就是上面说得位数组,当HFile很大时,Data Block 就会很多,同时KeyValue也会很多,需要映射入位数组的rowKey也会很多,所以为了保证准确率,位数组就会相应越大,那Bloom Block也会越大,为了解决这个问题就出现了Bloom Index Block,一个HFile中有多个Bloom Block(位数组),根据rowKey拆分,一部分连续的Key使用一个位数组。这样查询rowKey就要先经过Bloom Index Block(在内存中)定位到Bloom Block,再把Bloom Block加载到内存,进行过滤。
hive整合hbase
create external table students_hbase ( id string, name string, age string, gender string, clazz string ) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties ("hbase.columns.mapping" = " :key, info:name, info:age, info:gender, info:clazz ") tblproperties("hbase.table.name" = "default:student");

    推荐阅读