为什么Hbase按前缀查询慢

目录

问题

一、原因分析

二、解决方法

1.配合指定setStartRow

2.使用setRowPrefixFilter

总结


问题

使用hbase shell时我们经常会按前缀查询,如下

scan 't1', {ROWPREFIXFILTER => 'row2'}

现在想在java client中实现类似的按前缀查询,如何做呢?网上给的解决方案大多是基于PrefixFilter的,代码如下

public void scaneByPrefixFilter(Table table, String rowPrifix) {
   try {
       Scan s = new Scan();
       s.setFilter(new PrefixFilter(rowPrifix.getBytes()));
       ResultScanner rs = table.getScanner(s);
       for (Result r : rs) {
          KeyValue[] kv = r.raw();
          for (int i = 0; i < kv.length; i++) {
              System.out.print(new String(kv[i].getRow()) + "  ");
              System.out.print(new String(kv[i].getFamily()) + ":");
              System.out.print(new String(kv[i].getQualifier()) + "  ");
              System.out.print(kv[i].getTimestamp() + "  ");
              System.out.println(new String(kv[i].getValue()));
          }
      }
   } catch (IOException e) {
         e.printStackTrace();
   }
}

问题来了,在超大数据海量数据时,如上前缀匹配查询非常慢,具体是什么原因,如何解决呢?

一、原因分析

首先要理解hbase查询快的原理,参考这里META表中存储的是按照有序保存的row key分段区间对应的region位置,ROOT中又是存储的对应META表的位置,相当于3次二分查找快速定位到具体的region上的数据。

但是如果这里单纯指定PrefixFilter,查找时需要扫描全表匹配到对应的前缀输出,当然查询会慢。那么最关键的是如何跳过全表扫描,直接快速定位到开始地方。

二、解决方法

1.配合指定setStartRow

scan.setStartRow(rowkeyPrefix.getBytes());
scan.setFilter(new PrefixFilter(rowkeyPrefix.getBytes()));
这里其实就是尽快找到rowkeyPrefix匹配的行,开始匹配前缀,直到前缀产生不匹配

2.使用setRowPrefixFilter

具体实现如下:

    public Scan setRowPrefixFilter(byte[] rowPrefix) {
        if (rowPrefix == null) {
            this.setStartRow(HConstants.EMPTY_START_ROW);
            this.setStopRow(HConstants.EMPTY_END_ROW);
        } else {
            this.setStartRow(rowPrefix);
            this.setStopRow(this.calculateTheClosestNextRowKeyForPrefix(rowPrefix));
        }

        return this;
    }

可以看下源码,因为hbase输入包含startRow,不包含endRow,所以直接指定这两者也可以快速scan,但是计算endRow比较麻烦,所以可以看到setRowPrefixFilter就是帮我们计算了结束位置。

使用时如下指定前缀即可

scan.setRowPrefixFilter(rowkeyPrefix.getBytes());

参考

1. https://community.cloudera.com/t5/Community-Articles/Recommended-Way-to-do-HBase-Prefix-Scan-through-HBase-Java/ta-p/247271

2.https://stackoverflow.com/questions/17558547/hbase-easy-how-to-perform-range-prefix-scan-in-hbase-shell/38632100#38632100


总结

关于hbase的常见调用我封装了个简单库,可以直接使用,点击下载

博客https://blog.csdn.net/wenzhou1219
个人网站http://jimwen.net/

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页