昨天和一个互联网公司的leader争执关于get和scan的问题......记得以前粗略看过一次代码,清楚的记得在0.92.1版本里get最终是转化成scan来处理的......就怪自己当时手贱,脑子笨。没记清楚具体转化步骤......今天写个博客再来分析一下。有代码有真相!!!!!!
首先看下HTable 这个类里get方法
@Override
public Result get(final Get get) throws IOException {
return connection.getRegionServerWithRetries(
new ServerCallable<Result>(connection, tableName, get.getRow(), operationTimeout) {
public Result call() throws IOException {
return server.get(location.getRegionInfo().getRegionName(), get);
}
}
);
}
可以发现是调用HRegionServer里的get方法来运行的,再看HRegionServer里的get方法
public Result get(byte[] regionName, Get get) throws IOException {
checkOpen();
requestCount.incrementAndGet();
try {
HRegion region = getRegion(regionName);
return region.get(get, getLockFromId(get.getLockId()));
} catch (Throwable t) {
throw convertThrowableToIOE(cleanup(t));
}
}
这个方法很简单,首先根据regionName得到Region,然后调用region的get方法
public Result get(final Get get, final Integer lockid) throws IOException {
checkRow(get.getRow(), "Get");
// Verify families are all valid
if (get.hasFamilies()) {
for (byte [] family: get.familySet()) {
checkFamily(family);
}
} else { // Adding all families to scanner
for (byte[] family: this.htableDescriptor.getFamiliesKeys()) {
get.addFamily(family);
}
}
List<KeyValue> results = get(get, true);
return new Result(results);
}
这里面调用了另一个私有方法的get
private List<KeyValue> get(Get get, boolean withCoprocessor)
throws IOException {
List<KeyValue> results = new ArrayList<KeyValue>();
// pre-get CP hook
if (withCoprocessor && (coprocessorHost != null)) {
if (coprocessorHost.preGet(get, results)) {
return results;
}
}
Scan scan = new Scan(get);
RegionScanner scanner = null;
try {
scanner = getScanner(scan);
scanner.next(results);
} finally {
if (scanner != null)
scanner.close();
}
// post-get CP hook
if (withCoprocessor && (coprocessorHost != null)) {
coprocessorHost.postGet(get, results);
}
return results;
}
亮点出来了......get方法最终是转化成scan来处理的...... 后面的博客会继续分析scan ........