hbase上带rowfilter的filterlist与multiget的filterlist之间的区别

c86crjj0  于 2021-06-09  发布在  Hbase
关注(0)|答案(1)|浏览(456)

在实现从hbase表获取多个记录的过程中,我们遇到了一个关于获取记录的最佳方法的讨论。
第一个实现类似于:

FilterList filterList = new FilterList(Operator.MUST_PASS_ONE);
      for (String rowKey : rowKeys) {
        filterList.addFilter(new RowFilter(CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes(rowKey))));
      }

      Scan scan = new Scan();
      scan.setFilter(filterList);
      ResultScanner resultScanner = table.getScanner(scan);

第二个实现是这样的:

List<Get> listGet = rowKeys.stream()
          .map(entry -> {
            Get get = new Get(Bytes.toBytes(entry));
            return get;
          })
          .collect(Collectors.toList());
      Result[] results = table.get(listGet)

我直接看到的唯一区别是filterlist将执行完整的表扫描,而multiget不会执行任何类似的操作。
但是一个比另一个有什么好处呢?另外,当hbase发现filterlist中的所有过滤器都是rowfilters时,它是否会执行某种优化并执行multiget而不是执行全表扫描?

zzlelutf

zzlelutf1#

tldr:这取决于行的数量(读的和想要的),过滤器的数量,以及搜索数据的距离。
但是一个比另一个有什么好处呢?
一般来说,它有不同的用途。如果您想读取绝大多数数据并省略其中的一些数据,请使用带过滤器的扫描。如果您想在一个大表中只取几行,请使用multiget。
当我搜索答案时,我发现了一个关于hbase multiget vs scan with rowfilter的讨论。以下是要点:
scan将始终扫描所有行(或指定的开始行和停止行之间的所有行)。filter可以过滤出行,但它们都将被读取。
multiget为每个get执行一个seek(某种意义上)。
如果multiget中的get数与行总数相比非常小,那么最好使用multiget。但是,如果您能够在扫描操作中指定开始行和停止行,则扫描速度会更快(因为您限制了要读取的行数):

new Scan().withStartRow(startRow).withStopRow(stopRow)

另外,当hbase发现filterlist中的所有过滤器都是rowfilters时,它是否会执行某种优化并执行multiget而不是执行全表扫描?
不,我不认为它有任何优化。我认为,太多的过滤器甚至会减慢扫描速度,因为它必须通过每一行的所有过滤器。请参阅filterlist文档:
filterlist.operator.must \u pass \u one evaluates non lazy:始终计算所有筛选器。

相关问题