我有一个包含8G
数据的HBase表。
当我在该表上使用部分键扫描来检索给定键的值时,我得到几乎恒定的时间值检索。
当我使用Get
时,所花费的时间远远大于扫描时间。但是当我查看代码时,我发现Get
本身使用的是Scan
。
任何人都可以解释这个时间差异吗?
答案 0 :(得分:5)
正确,当您发出Get时,会在幕后发生扫描。 Cloudera's blog post确认了这一点:“每次发出一次获取或扫描时,HBase扫描(原文如此)通过每个文件来查找结果。”
我无法确认您的结果,但我认为线索可能在于您的“部分密钥扫描”。比较部分键扫描和获取时,请记住用于Get的行键可能比用于扫描的部分键长得多。
在这种情况下,对于Get,HBase必须进行确定性查找,以确定需要匹配的行键的确切位置并获取它。但是使用部分密钥,HBase不需要查找确切的密钥匹配,只需要找到该密钥前缀的更近似位置。
答案是:这取决于。我认为这取决于:
可能还有其他因素。
答案 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);