11

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

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

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

谁能解释一下这个时差?

4

2 回答 2

5

正确,当您发出 Get 时,会在幕后进行扫描。Cloudera 的博文证实了这一点:“每次发出 get 或 scan 时,HBase 扫描(原文如此)通过每个文件来查找结果。”

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

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

答案是:视情况而定。我认为这将取决于:

  1. 您的行键“模式”或组合
  2. Get 键和 Scan 前缀的长度
  3. 你有多少个地区

以及可能的其他因素。

于 2013-01-28T23:01:36.507 回答
2

在后端 HRegion 上,Scan 和 Get 的数量几乎相同。它们最终都由 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);
于 2014-09-19T19:33:37.477 回答