HBase分析之Get、Scan(二)RegionScanner
来源:互联网 发布:山东软件开发 编辑:程序博客网 时间:2024/06/07 00:00
这篇我们继续看moreRows = scanner.nextRaw(values, scannerContext);
,这里的scanner是通过HRegion#getScanner创建出来的一个RegionScannerImpl实例,他的nextRaw方法调用了RegionScannerImpl#nextInternal方法。这个方法主要目的是获取下一条数据放入results,并取得返回值表示是否还有更多的数据。
我们知道HBase没有建立索引,数据的查找是靠遍历文件实现的,所以查找下一行数据需要一个while循环。为了方便理解,代码稍有调整。
private boolean nextInternal(List<Cell> results, ScannerContext scannerContext) throws IOException { while (true) { ... }}
- 剥去while,看内部,首先从storeHeap里取了个值,第一次取得的值是null,后续会往storeHeap里塞数据。前一篇我们说过,多次的请求其实用的是同一个Scanner实例,所以可以在一次请求时,将值放入storeHeap,下一次请求还是可以从storeHeap里取出来。
Cell current = this.storeHeap.peek();byte[] currentRow = null;int offset = 0;short length = 0;if (current != null) { currentRow = current.getRowArray(); offset = current.getRowOffset(); length = current.getRowLength();}
- 判断当前数据是否是停止行,如果是停止行,就直接返回false,表示没有更多数据了。这里就是客户端设置scan.setStopRow可以提高效率的原因,因为直接return了false,所以就不会继续遍历了。
boolean stopRow = isStopRow(currentRow, offset, length);...if (stopRow) { return scannerContext.setScannerState(NextState.NO_MORE_VALUES).hasMoreValues();}
- 接着调用过滤器判断下一步的行为,如果这条数据无法满足filter的要求,就再判断下是否还有更多数据,没有就返回,有就continue while循环。Filter曾经被人诟病,即使后续的数据无法满足filter要求了,也必须遍历完,所以这里多出了个isFilterDoneInternal方法,来判断是否退出循环,返回false。
if (filterRowKey(currentRow, offset, length)) { if (isFilterDoneInternal()) { return scannerContext.setScannerState(NextState.NO_MORE_VALUES).hasMoreValues(); } boolean moreRows = nextRow(scannerContext, currentRow, offset, length); if (!moreRows) { return scannerContext.setScannerState(NextState.NO_MORE_VALUES).hasMoreValues(); } results.clear(); continue;}
- 这个时候,stopRow和filterRowKey都放行了,可以读取数据了。
populateResult(results, this.storeHeap, scannerContext, currentRow, offset, length);
这个方法里遍历数据,查找到下一行。populateResult的遍历和外层nextInternal遍历的差别在于,populateResult遍历负责找齐一行数据的所有列,从他while循环的条件moreCellsInRow就能看出来,外层的遍历负责对这一行数据进行过滤,包括stopRow、Filter。其他方法都很简单,就看heap.next(results, scannerContext);
方法,这里的heap就是this.storeHeap。
private boolean populateResult(List<Cell> results, KeyValueHeap heap, ScannerContext scannerContext, byte[] currentRow, int offset, short length) throws IOException { Cell nextKv; ... do { heap.next(results, scannerContext); nextKv = heap.peek(); // 看下一行数据的row是不是和当前行一样 moreCellsInRow = moreCellsInRow(nextKv, currentRow, offset, length); if (!moreCellsInRow) incrementCountOfRowsScannedMetric(scannerContext); ... } while (moreCellsInRow); ... return nextKv != null;}
再看heap.next(results, scannerContext);
方法,这里调用了current,即StoreScanner来读取下一行数据,StoreScanner.next放到下一篇来说。
@Overridepublic boolean next(List<Cell> result, ScannerContext scannerContext) throws IOException { ... InternalScanner currentAsInternal = (InternalScanner)this.current; boolean moreCells = currentAsInternal.next(result, scannerContext); ... return moreCells;}
- 取完数据,再看看下一行数据是否是stopRow
Cell nextKv = this.storeHeap.peek();stopRow = nextKv == null || isStopRow(nextKv.getRowArray(), nextKv.getRowOffset(), nextKv.getRowLength());
- 如果这次没找到数据,且不是停止行,就继续while遍历。
if (results.isEmpty()) { incrementCountOfRowsFilteredMetric(scannerContext); boolean moreRows = nextRow(scannerContext, currentRow, offset, length); if (!moreRows) { return scannerContext.setScannerState(NextState.NO_MORE_VALUES).hasMoreValues(); } if (!stopRow) continue;}
- 最后判断一次stopRow,这样查找就完事了。
if (stopRow) { return scannerContext.setScannerState(NextState.NO_MORE_VALUES).hasMoreValues();} else { return scannerContext.setScannerState(NextState.MORE_VALUES).hasMoreValues();}
下篇继续看HBase分析之StoreScanner
-END-
阅读全文
0 0
- HBase分析之Get、Scan(二)RegionScanner
- HBase分析之Get、Scan(一)
- HBase分析之Get、Scan(三)StoreScanner
- Hbase源码研究(二)-------get最终转化为scan来处理(1)
- Hbase 之 scan
- hbase源码学习之GET操作之get转化为scan
- HBase的scan源码分析客户端部分之整体流程(一)
- HBase scan的客户端分析
- hbase:单机环境搭建、hbase表操作示例(create, list, put, get, scan, disable, drop...)
- hbase学习记录之scan
- hbase源码分析HTable ->getScanner(final Scan scan)源码分析
- Hbase源码研究(三)-------get最终转化为scan来处理(2)
- hbase源码系列(十二)Get、Scan在服务端是如何处理
- HBase源码系列(五)Get、Scan在服务端是如何处理的?
- HBase 0.92.1 Scan 源码详细分析
- HBase的Scan实现源码分析
- go-hbase的Scan模型源码分析
- HBase源码分析之BlockCache二:BucketCache
- 备忘学习OpenCV中遇到的问题,不定期更新
- poj 1050最大子矩阵
- 林纳斯·托瓦斯(Linux内核之父)
- 赋值运算符及扩展的赋值运算符
- hdu 1811 经典拓扑排序+并查集
- HBase分析之Get、Scan(二)RegionScanner
- vmware虚拟机安装CentOS7后网络配置
- 一些android预装应用名字对应关系
- linux 下vi编辑的一些实用命令
- 大数--hdu5920 Ugly Problem
- KNN简单实现
- 欢迎使用CSDN-markdown编辑器
- html&css基础总结
- 使用国内镜像源来加速python pypi包的安装和tornado 4.5.2的安装