日期:2014-05-16 浏览次数:20624 次
分析版本为hbase 0.94
附上趋势团队画的图:

rpc角色表:
| HBase通信信道 | HBase的通信接口 | |
| 客户端 | 服务端 | |
| HBase Client | Master Server | HMasterInterface | 
| HBase Client | Region Server | HRegionInterface | 
| Region Server | Master Server | HMasterRegionInterface | 
客户端发起请求:
htable.get(Get)
public Result get(final Get get) throws IOException {
return new ServerCallable<Result>(connection, tableName, get.getRow(), operationTimeout) {
public Result call() throws IOException {
return server.get(location.getRegionInfo().getRegionName(), get);
}
}.withRetries();
}
调用get方法后,客户端进入睡眠,睡眠时间为pause * HConstants.RETRY_BACKOFF[ntries];
pause= HBASE_CLIENT_PAUSE(1秒)
RETRY_BACKOFF[] = { 1, 1, 1, 2, 2, 4, 4, 8, 16, 32 };
有结果则中断执行返回rpc结果,否则重试十次(默认DEFAULT_HBASE_CLIENT_RETRIES_NUMBER=10)
通过HConnectionManager的getHRegionConnection方法获取连接
通过HRegionServer的get方法获取结果
服务器端:
当regionserver 收到来自客户端的Get请求时,调用接口
在HRegion中
Scan scan = new Scan(get); 
会先根据设置的columnFamily存放familyMap对  ----  columnFamily:null
public Get addFamily(byte [] family) {
familyMap.remove(family);
familyMap.put(family, null);
return this;
}
如果查询的family不在htableDescriptor中,返回错误
scanner = getScanner(scan);
public RegionScanner getScanner(Scan scan) throws IOException {
return getScanner(scan, null);
}
additionalScanners为null 所以在RegionScannerImpl的构造中只会使用StoreScanner
return instantiateRegionScanner(scan, additionalScanners);
return new RegionScannerImpl(scan, additionalScanners);
RegionScannerImpl 是 HRegion中的子类
for (Map.Entry<byte[], NavigableSet<byte[]>> entry :
scan.getFamilyMap().entrySet()) {
Store store = stores.get(entry.getKey());
StoreScanner scanner = store.getScanner(scan, entry.getValue());
scanners.add(scanner);
}
按照familyMap的数量存放对应数量的 StoreScanner
Hregion initialize时会对应每个columnFamily存放一个stores
Future<Store> future = completionService.take();
Store store = future.get();
this.stores.put(store.getColumnFamilyName().getBytes(), store);
scanners 添加从Store中获取的scanner
store.getScanners(cacheBlocks, isGet,
isCompaction, matcher)
Store 类: