Hbase 查询过程详解(基于hbase0.98版本后分析的)
1、查询第一步是根据rowkey获取所在region信息
hbase0.96版本后删除了root 表,因为觉的目的是根据rroot表获取meta地址,过程是通过zookeeper获取root表地址,在根据root表记录meta表地址进行访问,还不如和zookeeper通讯一次。新增了namespace,详细见patch设计(https://issues.apache.org/jira/browse/HBASE-8015)
Meta的地址存放在zookeeper的(老版本是存放在root表里)如图:
Meta 表结构:
每条Row记录了一个Region的信息。首先是RowKey,RowKey由三部分组成:TableName, StartKey 和 RegionId。RowKey存储的内容我们又称之为Region的Name。用来存放Region的文件夹的名字是RegionName的Hash值,因为RegionName可能包含某些非法字符。现在你应该知道为什么RegionName会包含非法字符了吧,因为StartKey是被允许包含任何值的。将组成RowKey的三个部分用逗号连接就构成了整个RowKey,这里TimeStamp使用十进制的数字字符串来表示的。
regioninfo该列包含了META表的region信息:region名称、开始rowkey、结束rowkey、encode值:
a)region名称的组成规则:表名称+”,”+startKey+”,”+regionId,regionId的组成规则是:创建region时的时间戳+”.”+encode值(旧版hbase的regionId只有时间戳)+“.”
b)startKey,region的开始key,第一个region的startKey是空字符串;
c)endKey,region的结束key,最后一个region的endKey是空字符串;
d)encode值,该值会作为hdfs文件系统的一个目录,如上图encode值为:da1aec29c13725e29786e920bcc2d7b0,存放如下如图:
每次查询meta表后,客户端都有有region location info cache
下面就讲讲定位到region后的查询过程,首先一个store和column family是一一对应的。每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。什么是相同的IO特性,其实这个是由业务决定的。
前面的大家都弄明白了吧,下面我介绍下的client与region server查询交互过程。
1、查询memstore[memstore是是一个按key排序的树形结构的缓冲区],即写内存是否存储rowkey数据,如果有就返回,没有进行第二步查询;
2、查询region server的读缓存BlockCache 是否存在rowkey对应数据,如果有就返回,没有的话就行进行第三步查询。
3、在HFile里面根据rowkey查询数据,不管有没有都返回到client。
HFile的核心设计思想是分块和分级[查询速度也相对的快了]:
查询数据block的次数和HFile内部数据分开+索引分块
1、bloomfilter改进查找次数
2、hbase的三维顺序,按照rowkey,column,ts进行排序,rowkey和column是升序,
ts是降序
3、对于一次随机读block的访问顺序是bloomblock(多次) 、indexblock(1次) 、datablock(1次)
分块+分级索引(RootDataIndex、 IntermediateLevel ROOT INDEX 【备选如果HFile size 过大,就启用】、Leaf index block)
blockCache的优化和HFile V2格式我的另外两个博客文章单独介绍。
转载请附原文链接:http://blog.csdn.net/map_lixiupeng/article/details/40857825