大规模导出线上HBsase数据出现的问题总结

场景再现:

公司使用HBase作为底层存储方案,但随着业务的发展,数据量越来越大,理论上来说只要一直加机器就不存在任何问题,但这显然是不可能的。我们提出的解决方案是将一年以上的数据作为冷数据从HBase中导出来进行压缩后存到HDFS中,如果业务方要分析这部分的数据可以再关联hive表用sparkSQL做数据挖掘等。在删数据前必须要把HBase中的数据导出到HDFS中。


解决过程:

  因为我们一直使用sqoop作为数据导入导出的工具,它原生不支持HBase数据导入导出,于是在其基础上做了二次开发,其实就是mapreduce程序,但只需要map部分。
      其中比较核心的部分是如何选用HBase过滤器,开始时想的比较简单,因为想把历史数据导出来,自然的想到用timeRange过滤指定天数的数据。于是其中scan的代码如:
scan.setTimeRange(startTime, endTime);
      用过的童鞋会发现导出来的数据会少一些字段,这是因为timestamp是列的属性,我们业务中一行中每个列的写入时间不同,所以用这种方式导出来的会少数据。更重要的是这种方式是扫描每一个列的时间戳,所以效率是所有方式中最低的。同时storm会实时的消费硬件上传到kafka的数据将计算结果写入到HBase的表中提供给业务实时查询,timeRange方式会将整个HBase集群的IO占满,导致数据写不进HBase,为此接到不少业务方投诉。
实践发现timeRange并不可行,玩过HBase的肯定都会想到用filter,这种与rowkey的设计有关,我们的rowkey前面是设备唯一标识,后面部分是时间戳。所以最先想到的是rowfilter,它只会扫rowkey,所以效率会高很多。比较器用RegexStringComparator和SubStringComparator,两种比较器都只能和EQUAL和NOT_EQUAL运算符搭配使用。调试完毕,这次学乖了,晚上在线上测试,并实时观察对线上业务的影响。开始运行一会后就报了rpc time out的异常,查资料发现是rpc连接超时,它默认是60s,我调到5分钟。程序可以运行了,数据也在导,但非常慢,也影响HBase数据的写入,kafka队列中的数据在不断积压。查HBase官方文档是这么说的:基于字符串的比较器,如RegexStringComparator和SubStringComparator,很消耗资源,因为每次比较时它们都需要将给定的值转化为string,截取字符串和正则式的处理也需要花费额外时间。但按我的理解求正则和截取字符串在regionserver上运行的话,应该只消耗CPU资源,不应该这么慢,但最后也没找到原因。
继续看HBase文档,发现FuzzyRowFilter是按照模糊匹配过滤数据的,符合现在的需求,测试后果然效率提高了很多,而且以其它业务的影响很小(不是没有,这也说明HBase在资源隔离上做的不好),代码如下:
List<Pair<byte[],byte[]>> pairList = new ArrayList<>();
Pair<byte[],byte[]> p = new Pair<>(Bytes.toBytes(str.toString()),b);
pairList.add(p);
Filter filter = new FuzzyRowFilter(pairList);
scan.setFilter(filter);
     其中参数可以查阅文档,按业务需求变化。其中FuzzyRowFilter的参数是List,所以可以传入多个匹配规则,我们的另一张表就是这样导出的,因为它的rowkey不定长,有兴趣的同学可以试试。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值