在实现从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而不是执行全表扫描?
1条答案
按热度按时间zzlelutf1#
tldr:这取决于行的数量(读的和想要的),过滤器的数量,以及搜索数据的距离。
但是一个比另一个有什么好处呢?
一般来说,它有不同的用途。如果您想读取绝大多数数据并省略其中的一些数据,请使用带过滤器的扫描。如果您想在一个大表中只取几行,请使用multiget。
当我搜索答案时,我发现了一个关于hbase multiget vs scan with rowfilter的讨论。以下是要点:
scan将始终扫描所有行(或指定的开始行和停止行之间的所有行)。filter可以过滤出行,但它们都将被读取。
multiget为每个get执行一个seek(某种意义上)。
如果multiget中的get数与行总数相比非常小,那么最好使用multiget。但是,如果您能够在扫描操作中指定开始行和停止行,则扫描速度会更快(因为您限制了要读取的行数):
另外,当hbase发现filterlist中的所有过滤器都是rowfilters时,它是否会执行某种优化并执行multiget而不是执行全表扫描?
不,我不认为它有任何优化。我认为,太多的过滤器甚至会减慢扫描速度,因为它必须通过每一行的所有过滤器。请参阅filterlist文档:
filterlist.operator.must \u pass \u one evaluates non lazy:始终计算所有筛选器。