MultiRowRangeFilter:如何限制每个RowRange的结果?

时间:2018-07-27 10:16:26

标签: hbase google-cloud-bigtable

我正在尝试利用HBase MultiRowRangeFilter,以最大程度地减少往返服务器多次重复扫描的往返次数。但是,我无法弄清楚如何处理一个行范围可能有太多行的情况,这会阻止Scan返回来自其他范围的任何行。

例如,考虑具有以下行键结构和内容的表:

Bob|1|XXX (XXX is some random sequence)
Bob|1|XXX
Bob|1|XXX
Bob|2|XXX
Bob|2|XXX
Bob|2|XXX
Bob|3|XXX
Bob|3|XXX
Bob|3|XXX

如何在上表中进行一个Scan的操作,该操作将为每个Bob|~|的范围返回2行的最大值?

现在,伪代码看起来像这样:

private void getRanges(Table tbl, Integer max) throws IOException
{
    List<RowRange> rowrangeList = new ArrayList<RowRange>();
    for (Integer i = 1; i <= 3; i++)
    {
        String rowKey = "Bob|" + i;
        RowRange rowRange = new RowRange(rowKey.getBytes(), true, rowKey.getBytes(), true);
        rowrangeList.add(rowRange);
    }

    FilterList fList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
    fList.addFilter(new KeyOnlyFilter());
    fList.addFilter(new FirstKeyOnlyFilter());
    fList.addFilter(new PageFilter(max));
    fList.addFilter(new MultiRowRangeFilter(rowrangeList));

    Scan s = new Scan();
    s.setFilter(fList);

    ResultScanner scanner = tbl.getScanner(s);
    for (Result row : scanner)
    {
        System.out.println("Got row: " + new String(row.getRow()));
    }
    scanner.close();
}

但是这里有问题:

如果我们没有指定max数字并且在PageFilter(max)中省略了设置FilterList,这将起作用。我们可以在客户端过滤结果,但是表中可能有数百万行带有Bob...行键前缀的行,因此我们想在服务器端限制Scan的结果。

如果我们指定PageFilter(max),那么如果表中的行多于前缀为max的{​​{1}},那么我们将不返回任何前缀为Bob|1|的行,等等。

我们如何最好地做到这一点?再次,目标是一次对多个范围执行一次Bob|2|(以改进当前对每个子键重复执行Scan的功能,这似乎效率不高)。理想情况下,这对HBase和Bigtable都应该起作用,但是至少其中一个会有所帮助!

2 个答案:

答案 0 :(得分:1)

不幸的是,此功能本身不受支持。我最好的建议是并行发布行范围。实际上,这将改善您的总体延迟,因为单个读取请求中的多个行范围是按顺序处理的。

由于每个RPC的开销,使用此路由会稍微降低您的最大吞吐量。但是,如果您在每个范围内流回的行数很少,则工作将由响应处理控制,因此您应该不会看到太大的差异。

答案 1 :(得分:0)

Bob | 1将有几行?如果它不会无限增长,那么也许您可以调整架构,使Bob | 1是行键,而XXX是列名。然后可以使用ColumnPaginationFilter将列数限制为2?