java自定义 filter,HBase自定义Filter
必需要提前说明下:不建议使用自定义的Filter。所有的Filter都是在服务端生效:就是说需要将自定义的Filter封装为jar,上传到HBase的类路径下,并重启HBase使之生效。对于生产环境的HBase来说,重启通常是不能接受的。
Filter的设置是在客户端完成的,而Filter的逻辑是在HBase的服务端完成的,中间需要一次序列化。我试过几种序列化方案,不过protobuffer以外的其他几种效果不算好。HBase自带的Filter也是用protobuffer进行的序列化,因此使用protobuffer还可以少传几个包。
需要提前说明的已经说完了,开始进入正题。这次从一个案例开始说起:在HBase中存储着用户行为记录,行键设计为“uid(6位)+etime(时间戳/1000)+tid(7位)+顺序号(8位)”。其中uid为用户ID、etime为事件时间、tid为行为标签。目标是检索出某个用户在指定时间范围内的几种行为数据。
针对这个案例我们自定义一个CustomRowKeyFilter,并将一个用户ID、事件起止时间以及多个行为ID作为CustomRowKeyFilter的成员变量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
packagecom.zhyea.dev.hbase.filter;
importorg.apache.hadoop.hbase.Cell;
importorg.apache.hadoop.hbase.filter.FilterBase;
importorg.apache.hadoop.hbase.util.Bytes;
importjava.io.IOException;
publicclassCustomRowKeyFilterextendsFilterBase{
privatelongpid;
privatelongeventTime;
privateStringtids;
privatebooleanfilterOutRow=false;
publicCustomRowKeyFilter(long_pid,long_eventTime,String_tids){
this.pid=_pid;
this.eventTime=_eventTime;
this.tids=_tids;
}
@Override
publicbooleanfilterRowKey(byte[]data,intoffset,intlength){
StringrowKey=Bytes.toString(data,offset,length);
this.filterOutRow=check(rowKey);
returnthis.filterOutRow;
}
publicReturnCodefilterKeyValue(Cellv)throwsIOException{
if(this.filterOutRow){
returnReturnCode.NEXT_ROW;
}
returnReturnCode.INCLUDE;
}
privatebooleancheck(StringrowKey){
try{
if(rowKey.length()<7){
returntrue;
}
long_pid=Long.valueOf(rowKey.substring(0,6));
long_eTime=Long.valueOf(rowKey.substring(6,16));
long_tid=Long.valueOf(rowKey.substring(16,23));
if(this.pid!=_pid){
returntrue;
}
if(this.eventTime>_eTime){
returntrue;
}
if(!this.tids.contains(_tid+"")){
returntrue;
}
}catch(Exceptione){
returntrue;
}
returnfalse;
}
}
代码中继承了FilterBase类,可以减少一些结构性的代码工作。至于Filter是如何工作的,在网上找到的这张图应该描述得很清楚了:
前面的代码只是实现了Filter的处理逻辑。要想使用这个Filter还需要做一些序列化处理。如前面所说序列化方案选择的是protobuffer,这里需要先定义一个描述文件CustomRowKeyFilterProto.proto,内容如下:
1
2
3
4
5
6
7
8
9
10
packagefilter;
optionjava_package="com.zhyea.dev.hbase.filter.proto";
optionjava_outer_classname="CustomRowKeyFilterProto";
messageCustomRowKeyFilter{
requiredint64pid=1;
requiredint64eventTime=2;
requiredstringtids=3;
}
定义完成后,执行protoc命令:
1
protoc-I=./--java_out=../src/main/javaCustomRowKeyFilterProto.proto
其中“-I”指定了proto描述文件的父目录, “—java_out”指定了java类的类路径,具体请根据自己的情况进行设置。执行命令后会在包com.zhyea.dev.hbase.filter.proto下生成序列化工具类CustomRowKeyFilterProto.java。
接下来在CustomRowKeyFilter中重写Filter类的toByteArray()方法和parseFrom()方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
publicbyte[]toByteArray()throwsIOException{
CustomRowKeyFilterProto.CustomRowKeyFilter.Builderbuilder=CustomRowKeyFilterProto.CustomRowKeyFilter.newBuilder();
builder.setPid(this.pid);
builder.setEventTime(this.eventTime);
builder.setCids(this.tids);
returnbuilder.build().toByteArray();
}
publicstaticFilterparseFrom(finalbyte[]pbBytes)throwsDeserializationException{
CustomRowKeyFilterProto.CustomRowKeyFilterproto;
try{
proto=CustomRowKeyFilterProto.CustomRowKeyFilter.parseFrom(pbBytes);
}catch(InvalidProtocolBufferExceptione){
thrownewDeserializationException(e);
}
long_pid=proto.getPid();
long_eventTime=proto.getEventTime();
String_tids=proto.getCids();
returnnewCustomRowKeyFilter(_pid,_eventTime,_tids);
}
这样自定义Filter就完成了。剩下的事情就是将之打包并上传到HBase(每个RegionServer)的类路径下。然后就可以在程序中使用了。
现在再仔细想想这个程序,是否一定需要一个自定义Filter呢!我们已经将查询需要的所有元素都定义在行键里了。那么可以使用“uid+起始时间”作为startRow,“uid+结束时间”作为stopRow完成时间范围的匹配,使用RegexStringComparator来处理tid的匹配,这样直接使用HBase提供的RowFilter就能解决问题了。唯一需要注意的事情就是在设计表时多花些心思在行键上罢了。
就是这样。
参考文档
java自定义 filter,HBase自定义Filter相关推荐
- java sessionstate_在Java Web开发中自定义Session
Session在存储安全性要求较高的会话信息方面是必不可少的,对于分布式Web应用自定义Session支持独立的状态服务器或集群是必须的.本文就来教大家如何在Java Web开发中自定义Session ...
- Java三大器之过滤器(Filter)的工作原理和代码演示
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...
- Java学习日志Day41_过滤器Filter 接口_项目更新:后台管理/前台统一处理全局乱码and用户列表---删除以及分页功能
一.过滤器Filter 接口 1.导包: <groupId>com.qf</groupId> <artifactId>FilterAndJquery</art ...
- Java httpClient中实现自定义DNS服务器地址配置
这个故事从一个小的需求开始. 在知乎编辑器中,链接插入以后可以选择转化为一个链接卡片,用户体验太棒了.这么好的点子,我们必须学(chao)习(xi)过来啊. 这个事情就这么被安排给了我们的前端同学.. ...
- hbase自定义协处理器实现
hbase自定义协处理器实现 首先编写代码,继承BaseRegionObserver,在代码中添加输出信息到/opt/apps/hbase_logs/hbase.log,如果协处理器生效,就会输出信息 ...
- java web三大组件之filter过滤器
过滤器是java web中相当重要的组成成分,是JavaWeb三大组件之一,它与Servlet很相似.不过过滤器有以下三条特性: 过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servle ...
- java web自定义监听器_Android自定义监听器Listener(自定义Java Callback回调事件)
Callback回调事件介绍 Java或Android中创建异步回调最普遍的做法就是使用listener监听器或者observer观察者模式来解决,listener回调事件通常用于实现一个代码去监听另 ...
- 【Java TreeMap】测试TreeMap的使用、Comparabe自定义类的自定义排序方式
TreeMap TreeMap<键,值对>底层是红黑树,元素放进去之后会自动根据key排序. 测试代码 测试TreeMap的使用.Comparabe自定义类的自定义排序方式e packag ...
- 怎么在java中创建一个自定义的collector
文章目录 简介 Collector介绍 自定义Collector 总结 怎么在java中创建一个自定义的collector 简介 在之前的java collectors文章里面,我们讲到了stream ...
最新文章
- View事件分发机制(源码分析篇)
- Cannot send session cache limiter - headers already sent错误解决方法
- CF-311B Cats Transport(斜率优化DP)
- More Effective C# Item3 : 运行时检查泛型参数的类型并提供特定的算法
- MySQL账户安全设置
- 1主5从mysql数据库_MySQL主从复制虽好,能完美解决数据库单点问题吗?
- go struct结构
- PAT1057. 数零壹
- C++之---友元函数
- 国产达梦数据库管理系统-通过Excel文件导入数据
- linux netcat命令实例
- 网络:IP基础知识总结
- Android自动打开省电模式,常规省电模式 | Android 开源项目 | Android Open Source Project...
- MFC小游戏之坦克大战
- 【Python】数据分析.pandas.透视表与交叉表
- 码牛学院安卓Android移动互联网高级开发正式课学习笔记
- 四足机器人(一)----MATLAB simulink对四足机器人物理建模
- 电磁场与电磁波实验 01 - | 位移电流测量及电磁场与电磁波的存在实验
- 中英三校合作开发新电池结构,可用于改善可穿戴设备体验
- teamviewer 修改mac地址
热门文章
- linux下删除已经创建的数据库,MongoDB 数据库的创建和删除
- java web spark_spark-微型的Java Web框架 Spark Framework
- 生活中的算法的实际举例_驾校学的技术,在实际生活中,你能运用自如吗?
- 开红数显示服务器为空,网维大师常见问题:图标空白或红号问号
- for循环执行 mybatis_Mybatis中使用循环遍历
- 多元线性回归模型-数学建模类-matlab详解
- Python 小白从零开始 PyQt5 项目实战(2)菜单和工具栏
- Mac下配置sublime实现LaTeX
- java接口文档生成工具_【分享】接口文档生成工具apipost
- python 打卡程序_如何用python实现腾讯文档自动打卡并定时执行