10

我有一个 HBase 表,我需要从多个范围中获取结果。例如,我可能需要从第 1-6 行、第 100-150 行等不同范围获取数据……我知道对于每次扫描,我都可以定义起始行和停止行。但如果我有 6 个范围,我需要扫描 6 次。有什么方法可以让我从一次扫描或一次 RPC 中获取多个范围的结果?我的 HBase 版本是 0.98。

4

1 回答 1

6

过滤器支持扫描多个行键范围。它可以从每个区域服务器可以访问的传递列表中构造行键范围。

当只扫描一个小的行键范围时,HBase 非常有效。如果用户需要在一次扫描中指定多个行键范围,典型的解决方案是:

  1. 通过 FilterList 是行键过滤器的列表,
  2. 使用 HBase 之上的 SQL 层来连接两个表,例如 hive、phoenix 等。但是,这两种解决方案都效率低下。

    他们都不能利用范围信息在扫描期间执行快速转发,这非常耗时。如果范围的数量非常大(例如数百万),join 是一个合适的解决方案,尽管它很慢。
    但是,在某些情况下,用户希望指定要扫描的少量范围(例如,<1000 个范围)。在这种情况下,两种解决方案都不能提供令人满意的性能。

MultiRowRangeFilter 就是为了支持这样的用例(扫描多个行键范围),它可以从用户
指定的列表中构造行键范围,并在扫描过程中进行快进。因此,扫描将非常有效。

package chengchen;

import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.MultiRowRangeFilter;
import org.apache.hadoop.hbase.filter.MultiRowRangeFilter.RowKeyRange;
import org.apache.hadoop.hbase.util.Bytes;



public class MultiRowRangeFilterTest {
    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            throw new Exception("Table name not specified.");
        }
        Configuration conf = HBaseConfiguration.create();
        HTable table = new HTable(conf, args[0]);

        TimeCounter executeTimer = new TimeCounter();
        executeTimer.begin();
        executeTimer.enter();
        Scan scan = new Scan();
        List<RowKeyRange> ranges = new ArrayList<RowKeyRange>();
        ranges.add(new RowKeyRange(Bytes.toBytes("001"), Bytes.toBytes("002")));
        ranges.add(new RowKeyRange(Bytes.toBytes("003"), Bytes.toBytes("004")));
        ranges.add(new RowKeyRange(Bytes.toBytes("005"), Bytes.toBytes("006")));
        Filter filter = new MultiRowRangeFilter(ranges);
        scan.setFilter(filter);
        int count = 0;
        ResultScanner scanner = table.getScanner(scan);
        Result r = scanner.next();
        while (r != null) {
            count++;
            r = scanner.next();
        }
        System.out
                .println("++ Scanning finished with count : " + count + " ++");
        scanner.close();


    }

}

请参阅此测试用例以在 java 中实现

注意:但是,在我看来,这种要求 SOLR 或 ES 是最好的方法......您可以使用 solr 查看我的答案以获取高级架构概述。我建议因为 hbase 扫描大量数据会非常慢。

于 2017-02-02T06:33:57.040 回答