hbase 源代码分析(6)get 过程 详解
来源:互联网 发布:如何用php打开文件夹 编辑:程序博客网 时间:2024/05/18 12:32
上一个章节将getregionLocator的客户端分析完了,服务端就是一个scan方法,这个等到分析SCAN的时候再做说明。
上一章:hbase 源代码分析(5)regionLocator 获取region过程 详解
http://blog.csdn.net/chenfenggang/article/details/75041244
这一章节将分析GET过程。
**GET过程,
1)找到zk,拿到MATA里的RegionService地址。
2)访问第一个RegionService,获得表的region的ServiceName。
3)访问第二个RegionService,
4) 查看menStore里有没有数据。
5)否则去StoreFile 里找。这个存储在HDFS。所以需要加载HFile到内存中。**
入口:
Result result = htable.get(new Get("".getBytes()));
客户端的调用:
private Result get(Get get, final boolean checkExistenceOnly) throws IOException { ......... RegionServerCallable<Result> callable = new RegionServerCallable<Result>(this.connection, getName(), get.getRow()) { @Override public Result call(int callTimeout) throws IOException { ClientProtos.GetRequest request = RequestConverter.buildGetRequest(getLocation().getRegionInfo().getRegionName(), getReq); PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setPriority(tableName); controller.setCallTimeout(callTimeout); try { ClientProtos.GetResponse response = getStub().get(controller, request); if (response == null) return null; return ProtobufUtil.toResult(response.getResult(), controller.cellScanner()); } catch (ServiceException se) { throw ProtobufUtil.getRemoteException(se); } } }; return rpcCallerFactory.<Result>newCaller(rpcTimeout).callWithRetries(callable, this.operationTimeout); }
这个里面包含了
1)找到zk,拿到MATA里的RegionService地址。
2)访问第一个RegionService,获得表的region的ServiceName。
因为这个是getregionLocator。所以将不分析了。
直接调用caller.call()
ClientProtos.GetResponse response = getStub().get(controller, request);
这个直接通过clientProtos访问RSRPCService。
然后会转到HRegion里去,然后将get变成scan(get)
// 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); }
这里前后有两个钩子,可以自己去实现协处理,实现Region Coprocessor就行
在初始化的时候指定了为StoreScaner
for (Map.Entry<byte[], NavigableSet<byte[]>> entry : scan.getFamilyMap().entrySet()) { Store store = stores.get(entry.getKey()); KeyValueScanner scanner; try { scanner = store.getScanner(scan, entry.getValue(), this.readPt); } catch (FileNotFoundException e) { throw handleFileNotFound(e); }
并将结果放入storeHeap中
protected void initializeKVHeap(List<KeyValueScanner> scanners, List<KeyValueScanner> joinedScanners, HRegion region) throws IOException { this.storeHeap = new KeyValueHeap(scanners, region.comparator); if (!joinedScanners.isEmpty()) { this.joinedHeap = new KeyValueHeap(joinedScanners, region.comparator); } }
在store.getScanner中
@Override public KeyValueScanner getScanner(Scan scan, final NavigableSet<byte []> targetCols, long readPt) throws IOException { lock.readLock().lock(); try { KeyValueScanner scanner = null; if (this.getCoprocessorHost() != null) { scanner = this.getCoprocessorHost().preStoreScannerOpen(this, scan, targetCols); } if (scanner == null) { scanner = scan.isReversed() ? new ReversedStoreScanner(this, getScanInfo(), scan, targetCols, readPt) : new StoreScanner(this, getScanInfo(), scan, targetCols, readPt); } return scanner; } finally { lock.readLock().unlock(); } }
然后new的过程
List<KeyValueScanner> scanners = getScannersNoCompaction();里面 protected List<KeyValueScanner> getScannersNoCompaction() throws IOException { final boolean isCompaction = false; boolean usePread = get || scanUsePread; return selectScannersFrom(store.getScanners(cacheBlocks, get, usePread, isCompaction, matcher, scan.getStartRow(), scan.getStopRow(), this.readPt)); }
store.getScanners里面。
@Override public List<KeyValueScanner> getScanners(boolean cacheBlocks, boolean isGet, boolean usePread, boolean isCompaction, ScanQueryMatcher matcher, byte[] startRow, byte[] stopRow, long readPt) throws IOException { Collection<StoreFile> storeFilesToScan; List<KeyValueScanner> memStoreScanners; this.lock.readLock().lock(); try { storeFilesToScan = this.storeEngine.getStoreFileManager().getFilesForScanOrGet(isGet, startRow, stopRow); memStoreScanners = this.memstore.getScanners(readPt); } finally { this.lock.readLock().unlock(); }
这样就添加了storeFilesToScan和memStoreScanners
然后在peek出来,因为storeHeap有序。所以先查看memstore 然后在看StoreFile。
最后匹配
protected boolean nextRow(ScannerContext scannerContext, byte[] currentRow, int offset, short length) throws IOException { assert this.joinedContinuationRow == null: "Trying to go to next row during joinedHeap read."; Cell next; while ((next = this.storeHeap.peek()) != null && CellUtil.matchingRow(next, currentRow, offset, length)) { this.storeHeap.next(MOCKED_LIST); } resetFilters(); // Calling the hook in CP which allows it to do a fast forward return this.region.getCoprocessorHost() == null || this.region.getCoprocessorHost() .postScannerFilterRow(this, currentRow, offset, length); }
如果匹配到就可以返回,结束了。
get 过程到此结束。
- hbase 源代码分析(6)get 过程 详解
- hbase 源代码分析(5)regionLocator 获取region过程 详解
- hbase 源代码分析 (7) put 过程 详解
- hbase 源代码分析 (8) delete 过程 详解
- hbase 源代码分析 (15)compact 过程
- hbase 源代码分析 (17)MapReduce 过程
- hbase 源代码分析 (9) hbase启动过程
- hbase 源代码分析 (12) Master和RegionService 启动过程
- hbase 源代码分析 (19) HMaster 启动负载均衡过程分析
- HBase 0.99 源代码分析 - Master启动过程(1)
- HBase 0.99 源代码分析 - Master启动过程(2)
- HBase分析之Get、Scan(一)
- hbase 源代码分析(18)负载均衡
- HBase的get过程(一)
- 【HBase】查找一行记录(get)的执行过程
- HBase Client Get 源码分析
- hbase 源码分析 (14) spit 过程
- hbase 源代码解析(2)HAdmin 的表创建过程
- 释放linux的内存
- android的popwindow控件,及控件设为圆角
- Jquery 1.9.0 以上版本 $.browser未定义
- idea常用插件
- 了解Latch建议去看vage写的一系列本版精华贴
- hbase 源代码分析(6)get 过程 详解
- Pandas matplotlib 无法显示中文
- 将字符串中的多个连在一起的空格变成单个空格
- android apk安装过程源码解析
- 利用python内置函数,快速统计单词在文本中出现的次数
- 树莓派上搭建家用文件共享服务器
- 谈一谈JAVA程序员成长之路
- 1014. 福尔摩斯的约会
- 【剑指offer】面试题5:替换空格