发布于 

HbaseTemplate未复用Connection等坑

以前都是使用Hbase的java api,自己写getTable, 自己封装get、scan、Result解析等方法以实现查询等功能。

最近用springBoot写项目,需要查询Hbase,想到既然都用Spring了,直接就用它封装好的HbaseTemplate岂不美哉,人家spring封装的总比自己写的好吧。于是引入了spring-data-hadoop和spring-data-hadoop-hbase两个依赖,启动的时候注入相关参数,构造一个HbaseTemplate的Bean,再注入其他相关Bean中使用。

刚用起来貌似挺美好,但用着用着,发现两个比较坑的问题.

1. 可用方法太少

HbaseTemplate中只有基本的get、find、put方法,只能满足类似于一次只查一个rowKey、一次只返回一个列、一次只put一个值等这样简单的需求。要实现多行、多列查询,要不就用效率低下的scan方式,要不就多次调用方法,还要自己在外层封装。

好在HbaseTemplate中有一个public的execute方法,理论上所有查询、写入的操作,都是封装函数,最终调用这个execute方法完成请求。因此,要实现自己比较复杂的查询、写入的需求,就需要自己拓展这个HbaseTemplate类,封装参数解析结果并返回。

2. 未复用Connection

Hbase的链接创建是一个比较重的操作,首先需要去链接zookeeper获取hbase信息,然后再创建到hbase的链接。如果是大量频繁的对hbase的查询,当然是期望能够复用链接Connection。

我本以为都已经2.5.0版本了,spring好歹对HbaseTemplate中的connection做了池化吧。结果观察日志发现每次请求hbase都会去请求zookeeper,于是调试源码,发现每次获取完Table之后,table.close的时候,就把Connection也close掉了,坑爹啊,根本就没有复用。

要改写里面getTable的逻辑太复杂,我选择放弃….于是贪生怕死,选了简单点的办法,启动的时候不再构造HbaseTemplate了,而是选择构造一个Connection, 再注入Service中,当然,也要相应修改对hbaseTemplate方法的调用,简而言之,这个方法,几乎就是抛弃HbaseTemplate了,只是参考它的方法,封装成了自己的HbaseTemplate,考虑到在问题1中自己也已经拓展了很多方法,也算是求仁得仁了。

仅做记录和分享。