Hbase支持两种读读操作,Scan & Get两种,Get在hbase的内部也是会转换成startRow == endRow的操作,所以本文就只介绍Get操作。
Scan的实际执行者是RegionScannerImpl ,下面是一张整体ScannerImpl的调用图
关于Scan的参数:
Get和Scan其实是同一操作,get是startRow==endRow的Scan,不过在判断stopRow的时候会考虑stop的闭区间。
RegionScannerImpl内部保存所有的StoreScanner也是放在一个KeyValueHeap中,但是由于每个Scanner处于一个family,所以统一rowkey的话,一个StoreScanner中的Cell会一直保持较大/较小的排序,所以在这里可以每次heap.top一个scanner,然后批量取result。
batch,这个表示每次取出的同一rowkey下的Cell数量限制,默认是-1,不限制,取出这个rowkey下的所有Cell(但是family中有个配置可以限制这个的最大值),按照Cell的排序从小到大,知道limit为止,一个family没取够,下一个family继续。所以如果batch较小,可能会在client端一行数据返回两个Result。
Filter的行过滤、reset在这里体现,若是被过滤掉了且未到stopRow,则继续读下一行
Get是一次性的调用一个next(result.limit),scan是调用多次返回多个result返回给client
Scan开始之间会根据定义从region.mvcc中去除readpoint
Get:
按照RowKey获取唯一一条记录。get的方法处理分两种:设置了ClosestRowBefore和没有设置ClosestRowBefore的RowLock。
Scan:
按照指定的条件获取一批记录。
可以通过setCaching和setBatch方法提高速度;
可以通过setStartRow与setEndRow来限定范围;
可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础;
1. Hbase设计七大原则
1.1)每个region的大小应该控制在10G到50G之间;
1.2)一个表最好保持在 50到100个 region的规模;
1.3)每个cell最大不应该超过10MB
如果超过,应该有些考虑业务拆分,如果实在无法拆分,那就只能使用mob;
1.4)我们设置一个列族
1.5)列族名必须尽量短
因为我们知道在存储的时候,每个keyvalue都会包含列族名;
1.