HBase 源码阅读之 读过程及scanner
来源:互联网 发布:正规网络博客公司 编辑:程序博客网 时间:2024/06/08 08:42
看过Hbase 读流程的代码的同学 对scanner这个词应该不会陌生
Hbase 在读流程时 具体是怎么围绕scanner展开的,最近仔细地看了代码后算是弄清了
HBase中的scanner实例关系如下图
首先,无论是GET还是scan的读数据,都是从RegionScanner的next接口中获取
第二,scanner可分为两种InternalScanner和KeyValueScanner,区别如下:
1.InternalScanner,可以理解为包含其他scanner的scanner,它的主要接口为next(),作用是从其包含的scanner中获取下一个KeyValue,它的角色可以理解为雇佣KeyValueScanner
2.KeyValueScanner,从内存或文件中获取KeyValue的scanner,它的主要接口有peek(),seek(KeyValue key),next()等,其中next和peek都能获取scanner中的下一个KeyValue,但是next会移动iterator,peek不会,而seek就是将iterator定位到指定的KeyValue,如果不存在该KeyValue则定位到其后面的那个KeyValue,在scanner初始化的时候都会调用下seek接口,它的角色可以理解为服务InternalScanner
所以,对于图中的scanner, RegionScanner、StoreScanner属于InternalScanner,
而MemstoreScanner、StoreFileScanner、StoreScanner属于KeyValueScanner
第三,KeyValue 和 KeyValueScanner是可以比较大小的,即他们在优先队列里是排序存放的
1.KeyValue的大小比较规则,优先级从大到小依次为RowKey cf+cq timestamp type,
具体点比如说,在比较2个KeyValue时,先比较RowKey的大小('a' < 'b'),相同的情况下比较cf+cq的大小('cf1:q1'<'cf2:q1'<'cf2:q2'),如果还是相同的话就比较时间戳(3042211081<3042211080,注意 我没写错,你没看错,时间戳的long值越大,表示数据越新,在从小到大的队列中越靠前),如果上述仍然还相同则比较TYPE('DeleteFamily' < 'DeleteColumn' < 'Delete' < Put)
2.KeyValueScanner的大小比较规则:其大小有peek()获取到KeyValue大小决定,即
KeyValueScanner1.peek() < KeyValueScanner2.peek() 则KeyValueScanner1 < KeyValueScanner2
看明白以上3点后,则读的流程就比较好懂了,
1.RegionScanner中有一个scanner的优先队列,当然里面放的是StoreScanner
2.StoreScanner中也有一个scanner的优先队列,里面放着地是MemStoreScanner和StoreFileScanner,
3.RegionScanner通过调用next()获取数据时,其实际是从他的scanner队列中poll出一个StoreScanner,然后调用StoreScanner.next()来获取数据,最后再将该StoreScanner继续添加进优先队列中,从而保证队列中的scanner是一直正确有序的
4,3中的StoreScanner.next(),其实际是从他的scanner队列中poll出一个StoreFileScanner或者是MemStoreScanner,然后调用next(),再将该scanner添加进队列中
Hbase 在读流程时 具体是怎么围绕scanner展开的,最近仔细地看了代码后算是弄清了
HBase中的scanner实例关系如下图
首先,无论是GET还是scan的读数据,都是从RegionScanner的next接口中获取
第二,scanner可分为两种InternalScanner和KeyValueScanner,区别如下:
1.InternalScanner,可以理解为包含其他scanner的scanner,它的主要接口为next(),作用是从其包含的scanner中获取下一个KeyValue,它的角色可以理解为雇佣KeyValueScanner
2.KeyValueScanner,从内存或文件中获取KeyValue的scanner,它的主要接口有peek(),seek(KeyValue key),next()等,其中next和peek都能获取scanner中的下一个KeyValue,但是next会移动iterator,peek不会,而seek就是将iterator定位到指定的KeyValue,如果不存在该KeyValue则定位到其后面的那个KeyValue,在scanner初始化的时候都会调用下seek接口,它的角色可以理解为服务InternalScanner
所以,对于图中的scanner, RegionScanner、StoreScanner属于InternalScanner,
而MemstoreScanner、StoreFileScanner、StoreScanner属于KeyValueScanner
第三,KeyValue 和 KeyValueScanner是可以比较大小的,即他们在优先队列里是排序存放的
1.KeyValue的大小比较规则,优先级从大到小依次为RowKey cf+cq timestamp type,
具体点比如说,在比较2个KeyValue时,先比较RowKey的大小('a' < 'b'),相同的情况下比较cf+cq的大小('cf1:q1'<'cf2:q1'<'cf2:q2'),如果还是相同的话就比较时间戳(3042211081<3042211080,注意 我没写错,你没看错,时间戳的long值越大,表示数据越新,在从小到大的队列中越靠前),如果上述仍然还相同则比较TYPE('DeleteFamily' < 'DeleteColumn' < 'Delete' < Put)
2.KeyValueScanner的大小比较规则:其大小有peek()获取到KeyValue大小决定,即
KeyValueScanner1.peek() < KeyValueScanner2.peek() 则KeyValueScanner1 < KeyValueScanner2
看明白以上3点后,则读的流程就比较好懂了,
1.RegionScanner中有一个scanner的优先队列,当然里面放的是StoreScanner
2.StoreScanner中也有一个scanner的优先队列,里面放着地是MemStoreScanner和StoreFileScanner,
3.RegionScanner通过调用next()获取数据时,其实际是从他的scanner队列中poll出一个StoreScanner,然后调用StoreScanner.next()来获取数据,最后再将该StoreScanner继续添加进优先队列中,从而保证队列中的scanner是一直正确有序的
4,3中的StoreScanner.next(),其实际是从他的scanner队列中poll出一个StoreFileScanner或者是MemStoreScanner,然后调用next(),再将该scanner添加进队列中
0 0
- HBase 源码阅读之 读过程及scanner
- Memcached源码阅读之get过程
- Tomcat源码阅读之Init过程
- Tomcat源码阅读之Load过程
- Tomcat源码阅读之Engine启动过程
- Tomcat源码阅读之请求过程
- HBase Scanner
- HBase quota机制源码阅读
- Java 源码阅读过程
- Hbase源码之HMaster
- HBase源码之HRegionServer
- Hbase源码之事务处理
- Hbase Scanner 排序标准
- HBase Scanner扫描器
- java.lang之java.lang.Long源码阅读及分析
- java.lang之java.lang.String 源码阅读及分析
- java.lang之java.lang.Object源码阅读及分析
- 源码阅读之ArrayList
- RHCE考试经验
- 希尔排序
- 判断手机操作系统版本是否允许运行程序
- android学习日记03-第一次创建项目错误解决
- 【CodeForces】A. Dragons
- HBase 源码阅读之 读过程及scanner
- MS SQL SERVER 聚簇索引和非聚簇索引区别
- 1017. Queueing at Bank (25)
- Introduction to the spring framework(Spring框架简介)
- C++开发人脸性别识别总结
- 算法代码实现之堆排序,Golang(Go语言)实现
- android:ellipsize属性
- BZOJ3653: 谈笑风生
- 创建并打开文件