您的位置:首页 > 其它

Hbase-高级API-过滤器

2018-01-10 21:42 197 查看
Hbase的过滤器能帮助用户提高其处理表中数据的效率,过滤器分为Hbase预定义的过滤器和自定义的过滤器

过滤器简介

hbase中读取函数是get和scan,他们都支持直接访问数据和通过指定起止行健访问数据的功能,还可在查询中添加限制条件(坐标)来减少查询的数据量

但是它们缺少细粒度的查询功能,get和scan支持过滤器(细粒度的查询功能,正则表达式或值筛选)

用户还可继承Filter类来实现自己的需求,所有的过滤器都在服务器端生效,叫谓词下推(优化器可以将谓词过滤下推到数据源),这样保证被过滤掉的数据不会被传送到客户端



过滤器在客户端创建,通过RPC传送到服务器端,然后再服务器端执行过滤操作

过滤器层次结构

过滤器层次结构的底层是Filter和FilterBase抽象类(它们实现了过滤器的空壳和骨架,避免许多的结构代码)

大部分实体过滤器类一般直接继承自FilterBase,也有间接继承的类,使用流程相同

用户定义一个实体类,然后给get或scan实例

setFilter(filter)
//在实例化过滤器的时候,提供一些参数设定过滤器的用途


继承自CompareFilter类的过滤器,需要提供至少两个特定的参数,这两个参数被基类用来执行它的任务

比较运算符(参数一)

继承自CompareFilter的过滤器比基类多了一个compare方法,它需要传入参数定义比较的过程

LESS、LESS_OR_EQUAL、EQUAL、NOT_EQUAL、GREATER_OR_EQUAL、GREATER、NO_OP(排除一切值)


当过滤器被运用是,比较运算符可以决定什么被包含,什么被排除,帮助用户筛选数据的子集或一些特定的数据

比较器(参数二)

CompareFilter所需的第二个类类型就是比较器(comparator),比较器提供了许多的方法来比较不同的键值。比较器都继承自WritableByteArrayComparable(实现Writable和Comparable)类

//hbase原生比较器



后三种比较器只能与EQUAL、NOT_EQUAL运算符搭配

通常每个比较器都有一个带比较值参数的构造函数,需要定义一个值来跟每个单元格做比较(一些使用字节数组做参数,一些使用字符串做参数(当需要比较的参数是可读文本时))

基于字符串的比较器,如RegexStringComparator和SubstringComparator比基于字节数组的比较器更慢,更耗资源。因为每次比较时都需要将给定的值转换为字符串

比较过滤器(comparison filter)

用户创建实例时需要一个比较运算符和一个比较器实例,没一个比较器的构造方法都有一个从CompareFilter继承来的前签名方法(就是在实例化比较过滤器时需要提供两个参数)

CompareFilter(CompareOp valueCompareOp,WritableByteArrayComparable valueComparator)
//提供比较运算符和比较了类来让过滤器起作用


hbase 过滤器的本来目的是为了筛选无用的信息,不能用来指定用户需要哪些数据,而是在读取数据的过程中不返回用户不想要的信息。

基于CompareFilter的过滤处理过程和上面所描述的恰恰想反,他们返回匹配的值

行过滤器是使用行健来过滤数据的

//过滤器挑选特定的行
Configuration conf = HBaseConfiguration.create();

HTable table = new HTable(conf,Bytes.toBytes("testtable"));

Filter filter = new RowFilter(CompareFilter.CompareOp.NOT_EQUAL,
new BinaryComparator(Bytes.toBytes("row4")));
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"));
scan.setFilter(filter);

ResultScanner result = table.getScanner(scan);
for(Result res : result){
System.out.println(res);
}
result.close();

Filter filter1 = new RowFilter(CompareFilter.CompareOp.NOT_EQUAL,
new RegexStringComparator(".*2"));
//正则表达式,与比较运算符联系就是不包括带2的所有行
Scan scan1 = new Scan();
scan1.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"));
scan1.setFilter(filter1);

ResultScanner result1 = table.getScanner(scan1);
System.out.println("----------");
for(Result res : result1){

System.out.println(res);
}
result1.close();


筛选行健的过程,行健是按照字典序来排列的

列族过滤器(FamilyFilter)与行健过滤器相似,不过是比较列族的,通过组合不同的运算符合比较器,用户可以再列族一级筛选数据

//过滤器挑选特定的列族
Configuration conf = HBaseConfiguration.create();

HTable table = new HTable(conf,Bytes.toBytes("testtable"));

Filter filter = new FamilyFilter(CompareFilter.CompareOp.LESS,
new BinaryComparator(Bytes.toBytes("colfam2")));
Scan scan = new Scan();
scan.setFilter(filter);
int count=0;
ResultScanner result = table.getScanner(scan);
for(Result res : result){
System.out.println(res);
count++;
}
System.out.println("result:"+count);
result.close();


如果过滤器和get或者scan限定的条件不同的话结果会产生错误

列名过滤器

//过滤器筛选列
Configuration conf = HBaseConfiguration.create();

HTable table = new HTable(conf,Bytes.toBytes("testtable"));

Filter filter = new QualifierFilter(CompareFilter.CompareOp.LESS_OR_EQUAL,
new BinaryComparator(Bytes.toBytes("qual1")));
Scan scan = new Scan();
scan.setFilter(filter);
int count=0;
ResultScanner result = table.getScanner(scan);
for(Result res : result){
System.out.println(res);
count++;
}
System.out.println("result:"+count);
result.close();
//单独的一行使用过滤器
Get get = new Get(Bytes.toBytes("row1"));
get.setFilter(filter);
Result re = table.get(get);
System.out.println("result:"+re);


值过滤器 可以筛选特定的值的单元格。与 RegexStringComparator配合使用,有一些特定的比较器是只能与特定的运算符搭配使用。正则和子串比较器只能与EQUAL、NOT_EQUAL运算符搭配

Configuration conf = HBaseConfiguration.create();

HTable table = new HTable(conf,Bytes.toBytes("testtable"));

Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL,
new RegexStringComparator(".1"));
Scan scan = new Scan();
scan.setFilter(filter);
int count=0;
ResultScanner result = table.getScanner(scan);
for(Result res : result){
for(KeyValue kv : res.raw()){
System.out.println("kv:"+kv+"  result:"+Bytes.toString(kv.getValue()));
}
count++;
}
System.out.println("result:"+count);
result.close();

Get get = new Get(Bytes.toBytes("row1"));
get.setFilter(filter);
Result re = table.get(get);
System.out.println("result:"+re);


参考列过滤器 这是一种很复杂的过滤器,不仅仅通过指定信息筛选数据,它还允许指定一个参考列,并使用参考列控制其他列的过滤

参考列过滤器使用参考列的时间戳,并在过滤时包括所有与引时间戳相同的列

//构造方法
DependentColumnFilter(byte[] family,byte[] qualifier)
//使用时间戳

DependentColumnFilter(byte[] family,byte[] qualifier,boolean dropDependentColumn)

DependentColumnFilter(byte[] family,byte[] qualifier,boolean dropDependentColumn,CompareOp valueCompareOp,WritableByteArrayComparable valueComparator )
//启用valueFilter的功能


可以理解为valueFilter和一个时间戳过滤器的组合

dropDependentColumn参数设为false和true来决定参考列是丢弃还是保留(打不打印出来)

该过滤器不能与批处理器batch一起使用,因为过滤器需要查看整行的数据来决定那些数据过滤。而批处理可能导致取到的数据不包括参考列

例暂无

专用过滤器

hbase提供的第二类过滤器直接继承与filterbase,用于更特别的场景。其中的一些过滤器只能做行筛选,所以只适用于扫描操作

单列值过滤器

单列排除过滤器

前缀过滤器

分页过滤器

行键过滤器

首次行键过滤器

包含结束的过滤器

时间戳过滤器

列计数过滤器

列分页过滤器

列前缀过滤器

随机行过滤器

附加过滤器

跳转过滤器

全匹配过滤器

FilterList

FilterList组合多个过滤器,使用多维度共同限制返会结果

FilterList实现了Filter接口,通过组合多个过滤器来实现某种效果,从而代替该类过滤器

//构造器
FilterList(List<Filter> rowFilters)组合过滤器
FilterList(Operator operator)参数决定组合的结果
FilterList(Operator operator,List<Filter> rowFilters)


枚举参数参数Filter.Operator.
MUST_PASS_ALL   所有过滤器包含这个值时才包含到结果中
MUST_PASS_ONE   只要有一个过滤器包含值就包含在结果中


FilterList可以向已经存在的FilterList实例添加FilterList实例,来构建多级过滤器

也可以通过List来保证过滤器的顺序

自定义过滤器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息