汕头企业建站,域名申请阿里云,网站维护模板,中国各省旅游网站建设分析简介#xff1a;HBase的存储引擎是基于LSM-Like树实现的#xff0c;更新操作不会直接去更新数据#xff0c;而是使用各种type字段#xff08;put#xff0c;delete#xff09;来标记一个新的多版本数据#xff0c;采用定期compaction的形式来归档合并数据。这种数据结构…简介HBase的存储引擎是基于LSM-Like树实现的更新操作不会直接去更新数据而是使用各种type字段putdelete来标记一个新的多版本数据采用定期compaction的形式来归档合并数据。这种数据结构将写操作变得非常简单且高效但是却给读造成了很大的困扰。读取过程需要根据列族读取不同HFile中的数据还需要根据版本进行过滤同时对已经标记删除的数据也要进行过滤硬盘中的数据与MemStore中的数据重合时还需要执行合并最后在内存中拼接成一行完整的数据再向上返回。 本文粗粒度地展示了HBase的读取链路欢迎一起探讨交流
正文之前
在讲HBase的读路径时我们先来看几个简单的类图。
InternalScanner是一个Interface主要提供了两个方法next(ListCell result)方法——获取下一行的数据。而next(ListCell result, ScannerContext scannerContext)提供功能相同只不过允许传入一个ScannerContext用以记录当前scan任务的上下文判断是否可以提前结束、是否要去读下一列、是否要去读下一行等。并且发生在InternalScanner中的数据比较等操作都是基于byte[]而不用先转化为RowResults更加接近于数据在物理上的存储形式可以获得更高的性能。 KeyValueScanner也是一个接口换成CellScanner可能更容易理解。对它主要提供在一个“可读取的对象上”获取cell的能力。这里使用“可读取的对象”这个词主要是因为它可以是一个物理概念上的HFile但也可以是逻辑意义上有迭代读取能力的scanner。 最后一个关键的类就是KeyValueHeap该类实现了KeyValueScanner与InternalScanner接口具备了获取cell及获取行的能力。KeyValueHeap中还有一个关键的属性为heap它是一个PriorityQueueKeyValueScanner对象comparator CellComparatorImp即按照key的格式rowkey:family:qualifier:timestamp。即KeyValueHeap允许传入多个KeyValueScanner通过PriorityQueue的形式将这些scanner管理起来向上提供获取cell及获取行数据的能力 有了InternalScannerKeyValueScanner和KeyValueHeap其实已经可以做很多事情了。
我们知道HBase的查询抽象地来看的话是表现为下面这个流程的 即从不同的HFile中进行数据读取在内存中进行一个MergeSort拼接成一行数据向上返回。
你们看KeyValueScanner、InternalScanner是不是就像其负责中HFile的读取Scanner而KeyValueHeap负责的其实就是图中的MergeSort的任务。KeyValueHeap控制着下层KeyValueScanner、InternalScanner的数据读取KeyValueScanner、InternalScanner是真正读取数据的Scanner。
好大体的流程思路已经讲清楚了。其实HBase的读取流程远比这复杂涉及的对象也更多但有了上面的基础相信可以理解得很容易接下来我们来仔细看看HBase的读取流程。
正文
我们从RegionScanner出发仔细看看HBase的读取流程。 上图中的RegionScanner主要靠成员变量storeHeapjoinedHeapKeyValueHeap进行数据读取迭代。而StoreScanner也不是一个单纯的Scanner而是扮演了跟RegionScanner类似的角色它也拥有自己的heap以此来进行数据的读取。跟【正文之前】说的一样KeyValueHeap控制着下层KeyValueScanner、InternalScanner的数据读取KeyValueScanner、InternalScanner是真正读取数据的Scanner。只不过RegionScanner中多嵌了一层StoreScannerKeyValueHeap变成了这样的调用链路KeyValueHeap(RegionScanner)-KeyValueHeap(StoreScanner)
-KeyValueScanner,InternalScanner(StoreFileScanner及SegmentScanner)。
为什么HBase要这样封装
其实是为了抽象不同的功能。
简单来说
1StoreScanner是为了联合StoreFileScanner与SegmentScanner向上提供整行的数据迭代读取功能。
2而RegionScanner一方面是对获取的数据做了过滤功能另一方面是为了将全部数据分为两段获取形式storeHeap和joinedHeap用以优化性能。因为从storeHeap中获取的数据如果会被过滤那么就没有必要再获取joinedHeap中的数据了。
详细内容我们见下文。
HBase的读取任务开始之前需要构建初始的Scanner体系涉及RegionScanner与StoreScanner的对象初始化我们详细来看
1RegionScanner对象的初始化
1.建立RegionScanner对象准备开始Scan任务涉及的所有Scanner的生成。
2.根据scan任务涉及的所有column family在本region上分别会为其中的每个column family生成一个StoreScanner。如果开启了on-demand column family loading那么会根据传入FilterList的isFamilyEssential方法进行判断如果isFamilyEssential那么会将该StoreScanner放入storeHeap中否则放入joinedHeap中。
3.storeHeap和joinedHeap中存放StoreScanner的形式为PriorityQueue优先级为CellComparatorImp。
2StoreScanner对象的初始化
接下来我们介绍RegionScanner对象的初始化中我们一笔带过的StoreScanner的生成过程
1.根据scan.isReversed()控制StoreScanner中的Scanner的优先级顺序。
2.根据传入的scan信息生成matcher内置对象该对象在查询过程中会对StoreScanner读取的数据进行一个筛选。
3.根据scan信息startRowstopRow在storeEngine中查询出涉及的HStoreFile对这些HStoreFile分别建立StoreFileScanner组成scannerList并且以StoreFileComparators.SEQ_ID为优先级maxSequenceId升序FileSize降序BulkTime升序PathName升序。
4.对scannerList根据timestamp range, row key range, bloomFilter做一个过滤。
5.scannerList中剩余的scanner根据startRowstopRow将指针seek到正确的位置。
6.将scanners以PriorityQueue的形式组织优先级同样为CellComparatorImp。
PSStoreFileComparators.SEQ_ID —— Comparator.comparingLong(HStoreFile::getMaxSequenceId) .thenComparing(Comparator.comparingLong(new GetFileSize()).reversed()) .thenComparingLong(new GetBulkTime()).thenComparing(new GetPathName())
组建好需要Scanner体系之后后续就是读取流程了。
读取流程如下图所示 RegionScanner主要负责以下功能
其包含storeHeap与joinedHeap都为KeyValueHeap的对象实例heap底层是包含了多个StoreScanner组成的PriorityQueuecomparator CellComparatorImp。向上提供符合条件的整行数据的迭代查询。
1.循环从storeHeap上获取cell数据以此判断是否还存在待获取数据。如果没有return false。如果有
2.那么先从storeHeap上获取family essential相关的数据使用filter进行过滤。如果被过滤continue loop。如果没有
3.那么从joinedHeap上获取剩余数据返回。
StoreScanner主要负责以下功能
StoreScanner虽然是实现了KeyValueScanner和InternalScanner的类但主要靠其成员变量heapKeyValueHeap来完成必要的操作。heap由多个StoreFileScanner实例按照PriorityQueue组成comparator CellComparatorImp。
1.循环从heap中获取cell。
2.通过matcher匹配cell获得返回的MatchCode不同MatchCode会触发不同的操作见下表。 3.不停循环直到数据组成整行向上返回。
StoreScanner中KeyValueHeap的next功能
storeScanner中的heap.next()究竟做了什么简单来说做了以下两件事情1从current当前的StoreFileScanner不在heap中获取cell返回。2更新当前current把current放回heap重新排序再获取当前最优先的StoreFileScanner作为current。
具体做法如下
1.从当前的StoreFileScanner current中获取下一个cellkvReturn。再获取kvReturn往后的第一个cellkvNext
2.判断kvNext是否为空。为空代表当前current读取完毕需要从heap中获取下一个scanner记为current。不为空则
3.从当前heap中获取第一个scanner与current 进行对比。判断它们谁通过peek()获得的cell key最小如果scanner更小那么把current放回heap。重新heap.poll()获得最新current。
4.返回kvReturn cell。
至此整个HBase的读路径分析结束留待补充的点
1.Matcher的实现逻辑分析。
2.BloomFilter的过滤分析。
3.StoreFileScanner以下直到HDFS之间的链路分析中间涉及一个BlockCache。
原文链接
本文为阿里云原创内容未经允许不得转载。