关于hbase的read操作的深入研究 region到storefile过程
这里面说的read既包括get,也包括scan,实际底层来看这两个操作也是一样的。
我们将要讨论的是,当我们从一张表读取数据的时候hbase到底是怎么处理的。
分二种情况来看,第一种就是表刚创建,所有put的数据还在memstore中,并没有刷新到hdfs上;第二种情况是,该store已经进行多次的flush操作,产生了多个storefile了。
在具体说明两种情况前,先考虑下表的region的问题,如果表只有一个region,那么没有说的,肯定是要扫描这个唯一的region。假设该表有多个region,此时.META.表就派上用场了,hbase会首先根据你要扫描的数据的rowkey来判断到底该数据放在哪个region上,该region所在服务器地址,然后把数据读取的请求发送给该region server。好了,实际对数据访问的任务都会放在region server上执行,为了简单起见,接下来的讨论都是在单台region server上对单个region的操作。
首先来看第一种情况,表刚创建,所有put的数据还在memstore中,并没有刷新到hdfs上。这个时候数据是在memstore中,并没有storefile产生,理所当然,hbase要查找memstore来获得相应的数据。对于memstore或者storefile来说,内存中都有关于rowkey的索引的,所以对于通过rowkey的查询速度是非常快速的。通过查询该索引就知道是否存在需要查看的数据,已经该数据在memstore中的位置。通过索引提供的信息就很容易找得到所需要的数据。这种情况很简单。
在来看第二种情况,该store已经进行多次的flush操作,产生了多个storefile了。那么数据应该从哪里查呢?所有的storefile?别忘记还有memstore。此时memstore中可能还会有没来得及flush的数据呢。如果此时该region还有很多的文件,是不是所有的文件都需要查找呢?hbase在查找先会根据时间戳或者查询列的信息来进行过滤,过滤掉那些肯定不含有所需数据的storefile或者memstore,尽量把我们的查询目标范围缩小。
尽管缩小了,但仍可能会有多个文件需要扫描的。storefile的内部有三维有序的,但是各个storefile之间并不是有序的。比如,storefile1中可能有rowkey为100到110的记录,而storefile2可能有rowkey为105到115的数据,storefile的rowkey的范围很有可能有交叉。所以查询数据的过程也不可能是对storefile的顺序查找。
hbase会首先查看每个storefile的最小的rowkey,然后按照从小到大的顺序进行排序,结果放到一个队列中,排序的算法就是按照hbase的三维顺序,按照rowkey,column,ts进行排序,rowkey和column是升序,而ts是降序。
实际上并不是所有满足时间戳和列过滤的文件都会加到这个队列中,hbase会首先对各个storefile中的数据进行探测,只会扫描扫描那些存在比当前查询的rowkey大的记录的storefile。举例来说,我当前要查找的rowkey为108,storefile1中rowkey范围为100~104,storefile2中rowkey的范围为105~110,那么对于storefile1最大的rowkey为104,小于105,所以不存在比所查rowkey105大的记录,storefile并不会被加到该队列中。根据相同的规则,storefile2则会被添加到该队列中。
队列有了,下面开始查询数据,首先通过poll取出队列的头storefile,会从storefile读取一条记录返回;接下来呢,该storefile的下条记录并不一定是查询结果的下一条记录,因为队列的比较顺序是比较的每个storefile的第一条符合要求的rowkey。所以,hbase会继续从队列中剩下的storefile取第一条记录,把该记录与头storefile的第二条记录做比较,如果前者大,那么返回头storefile的第二条记录;如果后者大,则会把头storefile放回队列重新排序,在重新取队列的头storefile。然后重复上面的整个过程。这个过程比较烦,语言描述不清楚,代码会更加清晰。
这段代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public KeyValue next() throws IOException { if(this.current == null) { return null; } KeyValue kvReturn = this.current.next(); KeyValue kvNext = this.current.peek(); if (kvNext == null) { this.current.close(); this.current = this.heap.poll(); } else { KeyValueScanner topScanner = this.heap.peek(); if (topScanner == null || this.comparator.compare(kvNext, topScanner.peek()) >= 0) { this.heap.add(this.current); this.current = this.heap.poll(); } } return kvReturn; } |
以上的代码在KeyValueHeap.java类中。
举个例子来说明:表sunwg01,有两个storefile,storefile1中包括rowkey100,rowkey110;storefile2中包括rowkey104,rowkey108。我现在执行scan ‘sunwg01′扫描表sunwg01中的所有的记录。
根据前面提到的排序规则,队列中会有2个元素,按顺序分别为storefile1,storefile2。
1,取出storefile1中的第一条记录rowkey100,并返回该结果
2,取出storefile1中的下一条记录rowkey110,同时取出队列剩余storefile的第一条记录rowkey104,经过比较rowkey110大于rowkey104,则将storefile1放回队列中
3,因为队列是有序的队列,会重新对storefile进行排序,因为此时storefile1的最小rowkey为110,而storefile2的最小rowkey为104,所以排序的结果为storefile2,storefile1
4,重复上面的过程,直到查不到记录为止。
最后查到的结果为:rowkey100,rowkey104,rowkey108,rowkey110。
顺便说下block cache的事情,当从storefile中读数据的时候会首先查看block cache中是否有该数据,如果有则直接查block cache,就没必要查询hdfs;如果没有该数据,那么就只能去查hdfs了。这也是为了block cache的命中率对性能有很大影响的原因。
上面描述了从hbase中read的基本的过程,还有些细节没有具体说,但是大概过程应该是都说到了。
关于hbase的read操作的深入研究 region到storefile过程的更多相关文章
- Hbase优化:(待重点研究)
一.服务端调优 1.参数配置 1).hbase.regionserver.handler.count:该设置决定了处理RPC的线程数量,默认值是10,通常可以调大,比如:150,当请求内容很大(上MB ...
- hadoop执行hdfs文件到hbase表插入操作(xjl456852原创)
本例中需要将hdfs上的文本文件,解析后插入到hbase的表中. 本例用到的hadoop版本2.7.2 hbase版本1.2.2 hbase的表如下: create 'ns2:user', 'info ...
- hbase的常用的shell命令&hbase的DDL操作&hbase的DML操作
前言 笔者在分类中的hbase栏目之前已经分享了hbase的安装以及一些常用的shell命令的使用,这里不仅仅重新复习一下shell命令,还会介绍hbase的DDL以及DML的相关操作. hbase的 ...
- Hbase_02、Hbase的常用的shell命令&Hbase的DDL操作&Hbase的DML操作(转)
阅读目录 前言 一.hbase的shell操作 1.1启动hbase shell 1.2执行hbase shell的帮助文档 1.3退出hbase shell 1.4使用status命令查看hbase ...
- Hbase理论&&hbase shell&&python操作hbase&&python通过mapreduce操作hbase
一.Hbase搭建: 二.理论知识介绍: 1Hbase介绍: Hbase是分布式.面向列的开源数据库(其实准确的说是面向列族).HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hb ...
- HBase(2) Java 操作 HBase 教程
目录 一.简介 二.hbase-client 引入 三.连接操作 四.表操作 五.运行测试 FAQ 参考文档 一.简介 在上一篇文章 HBase 基础入门 中,我们已经介绍了 HBase 的一些基本概 ...
- Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作
Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作 1.sparkstreaming实时写入Hbase(saveAsNewAPIHadoopDataset方法 ...
- hbase日常运维管用命令,region管理
1 Hbase日常运维 1.1 监控Hbase运行状况 1.1.1 操作系统 1.1.1.1 IO 群集网络IO,磁盘IO,HDFS IO IO越大说明文件读 ...
- 使用Django.core.cache操作Memcached导致性能不稳定的分析过程
使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...
随机推荐
- python (2)xpath与定向爬虫
内容来自:极客学院,教学视频: 写在前面: 提取Item 选择器介绍 我们有很多方法从网站中提取数据.Scrapy 使用一种叫做 XPath selectors的机制,它基于 XPath表达式. 这是 ...
- HTML5列表、块、布局
一.列表 <ol> 无序列表 (每项前有.) <ul> 有序列表 (每项前有编号1,,2,3) <li> 列表项 <ul type=" ...
- GC之三--GC 触发Full GC执行的情况及应对策略
1.System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full GC的频率,也即增加了间歇性停顿的次数. ...
- linux 挂载(转载)
From:http://forum.ubuntu.org.cn/viewtopic.php?t=257333 用linux,就一定要用linux的方式去思维.嗯,说的容易做起来难.我的D盘哪去了?恐怕 ...
- 运用BigDecimal精确计算
package com.wzh.test; import java.math.BigDecimal; public class test { /** * @param args */ public s ...
- CSS语法与用法小字典
前言:这是上学时期对CSS学习的整理,一直没见过光,由于不是专门做前端开发的,难免写不到重点,但对于看懂CSS,和掌握一些基本的用法,熟悉里面的门路还是大有裨益的.由于是从word中贴过来的,排版和格 ...
- springmvc数据处理模型
1.ModelAndView 实现: @RequestMapping("/testModelAndView") public ModelAndView testModelAndVi ...
- java中传递数组的写法
var arr=["110","120","119"]; //如果浏览器不支持JSON,就使用json2.js,json2.js的源码放在最 ...
- Java String 的实例(02)
1.初始化数组以及数组的拷贝 int[] a={1,2,3,4}; //System.out.println(Arrays.toString(a)); a=new int[ ...
- @Valid springMVC bean校验不起作用
@RequestMapping("/add2") public String addStudentValid(@Valid @ModelAttribute("s" ...