HBase是怎样从HFile中找到某个rowkey

举报
一朵翔云 发表于 2020/08/05 16:37:02 2020/08/05
【摘要】 文章介绍HBase根据时间戳和查询列信息对file做一次过滤,缩小查询范围,查找rowkey的处理过程。

如果创建表时,指定了BloomFilter,那么就根据BloomFilter快速的判断该rowkey是否在这个HFile中。但BloomFilter也会存在错误率。所以主要来看下不使用BloomFilter下,是如何查找到rowkey在哪个HFile下。 

HBase首先根据时间戳和查询列的信息对file做一次过滤,将查询范围缩小。仍然需要扫描其余的文件,storeFile之间是无序的,而且StoreFilerowkey范围会有交叉,所以并不会按照StoreFile顺序的查找。HBase会首先查看每个StoreFile的最小的rowkey,然后按照从小到大的顺序进行排序,结果放到一个队列中。接下来只会扫描比查询Rowkey大的记录的StoreFile,下面开始查询数据,整个过程用到了类似归并排序的算法,首先通过poll取出队列的头storefile,会从storefile读取一条记录返回;接下来呢,该StoreFile的下条记录并不一定是查询结果的下一条记录,因为队列的比较顺序是比较的每个storefile的第一条符合要求的rowkey。所以,hbase会继续从队列中剩下的storefile取第一条记录,把该记录与头storefile的第二条记录做比较,如果前者大,那么返回头storefile的第二条记录;如果后者大,则会把头storefile放回队列重新排序,在重新取队列的头storefile。然后重复上面的整个过程,直到找到key所在的HFile。范围缩小到该HFile后,就根据HFile文件中的索引去定位到块,快速的找到对应的记录。单个HFile文件中的索引主要是根据索引块的大小来提升速率。

Region下单个HFile文件数越多,一次查询就会需要更多的IO操作,延迟必然会越来越大。

如下图一所示,随着数据写入不断增加,文件数不断增多,读取延时也在不断变大

image.png

文件数基本稳定,进而IO Seek次数会比较稳定,延迟就会稳定在一定范围。下图是不断写入数据,hfile数量变多,不断Compaction合成大文件,文件数量基本稳定,查询时延也基本稳定

image.png

HFile结构

image.png


HFile的数据块,元数据块通常采用压缩方式存储,压缩之后可以大大减少网络IO和磁盘IO

image.png

图中上面三层为索引层,在数据量不大的时候只有最上面一层,数据量大了之后开始分裂为多层,最多三层,如图所示。最下面一层为数据层,存储用户的实际keyvalue数据。这个索引树结构类似于InnoSQL的聚集索引,只是HBase并没有辅助索引的概念。

图中红线表示一次查询的索引过程(HBase中相关类为HFileBlockIndexHFileReaderV2),基本流程可以表示为:

1. 用户输入rowkeyfb,在root index block中通过二分查找定位到fb’a’’m’之间,因此需要访问索引’a’指向的中间节点。因为root index block常驻内存,所以这个过程很快。

2. 将索引’a’指向的中间节点索引块加载到内存,然后通过二分查找定位到fbindex ‘d’’h’之间,接下来访问索引’d’指向的叶子节点。

3. 同理,将索引’d’指向的中间节点索引块加载到内存,一样通过二分查找定位找到fbindex ‘f’’g’之间,最后需要访问索引’f’指向的数据块节点。

4. 将索引’f’指向的数据块加载到内存,通过遍历的方式找到对应的keyvalue

上述流程中因为中间节点、叶子节点和数据块都需要加载到内存,所以io次数正常为3次。但是实际上HBaseblock提供了缓存机制,可以将频繁使用的block缓存在内存中,可以进一步加快实际读取过程。所以,HBase中,通常一次随机读请求最多会产生3次io,如果数据量小(只有一层索引),数据已经缓存到了内存,就不会产生io


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。