必需要提前说明下:不建议使用自定义的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相关推荐

  1. java sessionstate_在Java Web开发中自定义Session

    Session在存储安全性要求较高的会话信息方面是必不可少的,对于分布式Web应用自定义Session支持独立的状态服务器或集群是必须的.本文就来教大家如何在Java Web开发中自定义Session ...

  2. Java三大器之过滤器(Filter)的工作原理和代码演示

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...

  3. Java学习日志Day41_过滤器Filter 接口_项目更新:后台管理/前台统一处理全局乱码and用户列表---删除以及分页功能

    一.过滤器Filter 接口 1.导包: <groupId>com.qf</groupId> <artifactId>FilterAndJquery</art ...

  4. Java httpClient中实现自定义DNS服务器地址配置

    这个故事从一个小的需求开始. 在知乎编辑器中,链接插入以后可以选择转化为一个链接卡片,用户体验太棒了.这么好的点子,我们必须学(chao)习(xi)过来啊. 这个事情就这么被安排给了我们的前端同学.. ...

  5. hbase自定义协处理器实现

    hbase自定义协处理器实现 首先编写代码,继承BaseRegionObserver,在代码中添加输出信息到/opt/apps/hbase_logs/hbase.log,如果协处理器生效,就会输出信息 ...

  6. java web三大组件之filter过滤器

    过滤器是java web中相当重要的组成成分,是JavaWeb三大组件之一,它与Servlet很相似.不过过滤器有以下三条特性: 过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servle ...

  7. java web自定义监听器_Android自定义监听器Listener(自定义Java Callback回调事件)

    Callback回调事件介绍 Java或Android中创建异步回调最普遍的做法就是使用listener监听器或者observer观察者模式来解决,listener回调事件通常用于实现一个代码去监听另 ...

  8. 【Java TreeMap】测试TreeMap的使用、Comparabe自定义类的自定义排序方式

    TreeMap TreeMap<键,值对>底层是红黑树,元素放进去之后会自动根据key排序. 测试代码 测试TreeMap的使用.Comparabe自定义类的自定义排序方式e packag ...

  9. 怎么在java中创建一个自定义的collector

    文章目录 简介 Collector介绍 自定义Collector 总结 怎么在java中创建一个自定义的collector 简介 在之前的java collectors文章里面,我们讲到了stream ...

最新文章

  1. View事件分发机制(源码分析篇)
  2. Cannot send session cache limiter - headers already sent错误解决方法
  3. CF-311B Cats Transport(斜率优化DP)
  4. More Effective C# Item3 : 运行时检查泛型参数的类型并提供特定的算法
  5. MySQL账户安全设置
  6. 1主5从mysql数据库_MySQL主从复制虽好,能完美解决数据库单点问题吗?
  7. go struct结构
  8. PAT1057. 数零壹
  9. C++之---友元函数
  10. 国产达梦数据库管理系统-通过Excel文件导入数据
  11. linux netcat命令实例
  12. 网络:IP基础知识总结
  13. Android自动打开省电模式,常规省电模式  |  Android 开源项目  |  Android Open Source Project...
  14. MFC小游戏之坦克大战
  15. 【Python】数据分析.pandas.透视表与交叉表
  16. 码牛学院安卓Android移动互联网高级开发正式课学习笔记
  17. 四足机器人(一)----MATLAB simulink对四足机器人物理建模
  18. 电磁场与电磁波实验 01 - | 位移电流测量及电磁场与电磁波的存在实验
  19. 中英三校合作开发新电池结构,可用于改善可穿戴设备体验
  20. teamviewer 修改mac地址

热门文章

  1. linux下删除已经创建的数据库,MongoDB 数据库的创建和删除
  2. java web spark_spark-微型的Java Web框架 Spark Framework
  3. 生活中的算法的实际举例_驾校学的技术,在实际生活中,你能运用自如吗?
  4. 开红数显示服务器为空,网维大师常见问题:图标空白或红号问号
  5. for循环执行 mybatis_Mybatis中使用循环遍历
  6. 多元线性回归模型-数学建模类-matlab详解
  7. Python 小白从零开始 PyQt5 项目实战(2)菜单和工具栏
  8. Mac下配置sublime实现LaTeX
  9. java接口文档生成工具_【分享】接口文档生成工具apipost
  10. python 打卡程序_如何用python实现腾讯文档自动打卡并定时执行