Scan和Get之间的性能差异?

时间:2013-01-27 08:10:42

标签: hbase

我有一个包含8G数据的HBase表。

当我在该表上使用部分键扫描来检索给定键的值时,我得到几乎恒定的时间值检索。

当我使用Get时,所花费的时间远远大于扫描时间。但是当我查看代码时,我发现Get本身使用的是Scan

任何人都可以解释这个时间差异吗?

2 个答案:

答案 0 :(得分:5)

正确,当您发出Get时,会在幕后发生扫描。 Cloudera's blog post确认了这一点:“每次发出一次获取或扫描时,HBase扫描(原文如此)通过每个文件来查找结果。”

我无法确认您的结果,但我认为线索可能在于您的“部分密钥扫描”。比较部分键扫描和获取时,请记住用于Get的行键可能比用于扫描的部分键长得多。

在这种情况下,对于Get,HBase必须进行确定性查找,以确定需要匹配的行键的确切位置并获取它。但是使用部分密钥,HBase不需要查找确切的密钥匹配,只需要找到该密钥前缀的更近似位置。

答案是:这取决于。我认为这取决于:

  1. 您的行键“架构”或组合
  2. 获取密钥的长度和扫描前缀
  3. 您有多少个地区
  4. 可能还有其他因素。

答案 1 :(得分:2)

在后端HRegion上,扫描和获取相当于几乎相同的事情。它们最终都由HRegion.RegionScannerImpl执行。请注意,该类中的get()实例化RegionScanner - 类似于调用Scan。

org.apache.hadoop.hbase.regionserver.HRegion.RegionScannerImpl

public List<Cell> get(Get get, boolean withCoprocessor)
throws IOException {

List<Cell> results = new ArrayList<Cell>();

// pre-get CP hook
if (withCoprocessor && (coprocessorHost != null)) {
   if (coprocessorHost.preGet(get, results)) {
     return results;
   }
}

Scan scan = new Scan(get);

对于get(),只返回一行 - 通过一次调用scanner.next():

RegionScanner scanner = null;
try {
  scanner = getScanner(scan);
  scanner.next(results);