<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          HBase 剖析 | HBase 讀鏈路解析

          共 4971字,需瀏覽 10分鐘

           ·

          2021-09-06 11:24

          正文之前

          在講HBase的讀路徑時(shí),我們先來(lái)看幾個(gè)簡(jiǎn)單的類圖。

          InternalScanner是一個(gè)Interface主要提供了兩個(gè)方法,next(List<Cell> result)方法——獲取下一行的數(shù)據(jù)。而next(List<Cell> result, ScannerContext scannerContext)提供功能相同,只不過(guò)允許傳入一個(gè)ScannerContext用以記錄當(dāng)前scan任務(wù)的上下文,判斷是否可以提前結(jié)束、是否要去讀下一列、是否要去讀下一行等。并且發(fā)生在InternalScanner中的數(shù)據(jù)比較等操作,都是基于byte[](而不用先轉(zhuǎn)化為RowResults),更加接近于數(shù)據(jù)在物理上的存儲(chǔ)形式,可以獲得更高的性能。

          KeyValueScanner也是一個(gè)接口,換成CellScanner可能更容易理解。對(duì),它主要提供在一個(gè)“可讀取的對(duì)象上”,獲取cell的能力。這里使用“可讀取的對(duì)象”這個(gè)詞,主要是因?yàn)樗梢允且粋€(gè)物理概念上的HFile,但也可以是邏輯意義上有迭代讀取能力的scanner。

          最后一個(gè)關(guān)鍵的類就是KeyValueHeap,該類實(shí)現(xiàn)了KeyValueScanner與InternalScanner接口,具備了獲取cell及獲取行的能力。KeyValueHeap中還有一個(gè)關(guān)鍵的屬性,為heap,它是一個(gè)PriorityQueue<KeyValueScanner>對(duì)象,comparator = CellComparatorImp(即按照key的格式:rowkey:family:qualifier:timestamp)。即KeyValueHeap允許傳入多個(gè)KeyValueScanner,通過(guò)PriorityQueue的形式將這些scanner管理起來(lái),向上提供獲取cell及獲取行數(shù)據(jù)的能力!

          有了InternalScanner,KeyValueScanner和KeyValueHeap其實(shí)已經(jīng)可以做很多事情了。

          我們知道,HBase的查詢抽象地來(lái)看的話,是表現(xiàn)為下面這個(gè)流程的:

          即從不同的HFile中進(jìn)行數(shù)據(jù)讀取,在內(nèi)存中進(jìn)行一個(gè)MergeSort,拼接成一行數(shù)據(jù)向上返回。

          你們看KeyValueScanner、InternalScanner是不是就像其負(fù)責(zé)中HFile的讀取Scanner,而KeyValueHeap負(fù)責(zé)的其實(shí)就是圖中的MergeSort的任務(wù)。KeyValueHeap控制著下層KeyValueScanner、InternalScanner的數(shù)據(jù)讀取,KeyValueScanner、InternalScanner是真正讀取數(shù)據(jù)的Scanner。

          好,大體的流程思路已經(jīng)講清楚了。其實(shí)HBase的讀取流程遠(yuǎn)比這復(fù)雜,涉及的對(duì)象也更多,但有了上面的基礎(chǔ)相信可以理解得很容易,接下來(lái)我們來(lái)仔細(xì)看看HBase的讀取流程。


          正文

          我們從RegionScanner出發(fā),仔細(xì)看看HBase的讀取流程。

          上圖中的RegionScanner主要靠成員變量storeHeap,joinedHeap(KeyValueHeap)進(jìn)行數(shù)據(jù)讀取迭代。而StoreScanner也不是一個(gè)單純的Scanner,而是扮演了跟RegionScanner類似的角色,它也擁有自己的heap,以此來(lái)進(jìn)行數(shù)據(jù)的讀取。跟【正文之前】說(shuō)的一樣,KeyValueHeap控制著下層KeyValueScanner、InternalScanner的數(shù)據(jù)讀取,KeyValueScanner、InternalScanner是真正讀取數(shù)據(jù)的Scanner。只不過(guò)RegionScanner中多嵌了一層StoreScanner(KeyValueHeap),變成了這樣的調(diào)用鏈路:KeyValueHeap(RegionScanner)->KeyValueHeap(StoreScanner)

          ->KeyValueScanner,InternalScanner(StoreFileScanner及SegmentScanner)


          為什么HBase要這樣封裝?

          其實(shí)是為了抽象不同的功能。

          簡(jiǎn)單來(lái)說(shuō),

          1)StoreScanner是為了聯(lián)合StoreFileScanner與SegmentScanner向上提供整行的數(shù)據(jù)迭代讀取功能。

          2)而RegionScanner,一方面是對(duì)獲取的數(shù)據(jù)做了過(guò)濾功能,另一方面是為了將全部數(shù)據(jù)分為兩段獲取形式(storeHeap和joinedHeap),用以優(yōu)化性能。因?yàn)閺膕toreHeap中獲取的數(shù)據(jù)如果會(huì)被過(guò)濾,那么就沒(méi)有必要再獲取joinedHeap中的數(shù)據(jù)了。

          詳細(xì)內(nèi)容我們見(jiàn)下文。


          HBase的讀取任務(wù)開(kāi)始之前需要構(gòu)建初始的Scanner體系,涉及RegionScanner與StoreScanner的對(duì)象初始化,我們?cè)敿?xì)來(lái)看:


          1)RegionScanner對(duì)象的初始化

          1.建立RegionScanner對(duì)象,準(zhǔn)備開(kāi)始Scan任務(wù)涉及的所有Scanner的生成。

          2.根據(jù)scan任務(wù)涉及的所有column family,在本region上分別會(huì)為其中的每個(gè)column family生成一個(gè)StoreScanner。如果開(kāi)啟了on-demand column family loading,那么會(huì)根據(jù)傳入FilterList的isFamilyEssential方法進(jìn)行判斷,如果isFamilyEssential,那么會(huì)將該StoreScanner放入storeHeap中,否則放入joinedHeap中。

          3.storeHeap和joinedHeap中存放StoreScanner的形式為PriorityQueue,優(yōu)先級(jí)為CellComparatorImp。

          2)StoreScanner對(duì)象的初始化

          接下來(lái)我們介紹RegionScanner對(duì)象的初始化中,我們一筆帶過(guò)的StoreScanner的生成過(guò)程:

          1.根據(jù)scan.isReversed()控制StoreScanner中的Scanner的優(yōu)先級(jí)順序。

          2.根據(jù)傳入的scan信息,生成matcher內(nèi)置對(duì)象,該對(duì)象在查詢過(guò)程中會(huì)對(duì)StoreScanner讀取的數(shù)據(jù)進(jìn)行一個(gè)篩選。

          3.根據(jù)scan信息startRow,stopRow在storeEngine中查詢出涉及的HStoreFile,對(duì)這些HStoreFile分別建立StoreFileScanner,組成scannerList,并且以StoreFileComparators.SEQ_ID為優(yōu)先級(jí)(maxSequenceId升序,F(xiàn)ileSize降序,BulkTime升序,PathName升序)。

          4.對(duì)scannerList根據(jù)timestamp range, row key range, bloomFilter做一個(gè)過(guò)濾。

          5.scannerList中剩余的scanner根據(jù)startRow,stopRow將指針seek到正確的位置。

          6.將scanners以PriorityQueue的形式組織,優(yōu)先級(jí)同樣為CellComparatorImp。


          PS:StoreFileComparators.SEQ_ID —— Comparator.comparingLong(HStoreFile::getMaxSequenceId)  .thenComparing(Comparator.comparingLong(new GetFileSize()).reversed())  .thenComparingLong(new GetBulkTime()).thenComparing(new GetPathName())


          組建好需要Scanner體系之后,后續(xù)就是讀取流程了。

          讀取流程如下圖所示:

          RegionScanner主要負(fù)責(zé)以下功能:

          其包含storeHeap與joinedHeap都為KeyValueHeap的對(duì)象實(shí)例,heap底層是包含了多個(gè)StoreScanner組成的PriorityQueue,comparator = CellComparatorImp。向上提供符合條件的整行數(shù)據(jù)的迭代查詢。

          1.循環(huán)從storeHeap上獲取cell數(shù)據(jù),以此判斷是否還存在待獲取數(shù)據(jù)。如果沒(méi)有,return false。如果有:

          2.那么先從storeHeap上獲取family essential相關(guān)的數(shù)據(jù),使用filter進(jìn)行過(guò)濾。如果被過(guò)濾,continue loop。如果沒(méi)有:

          3.那么從joinedHeap上獲取剩余數(shù)據(jù),返回。


          StoreScanner主要負(fù)責(zé)以下功能:

          StoreScanner雖然是實(shí)現(xiàn)了KeyValueScanner和InternalScanner的類,但主要靠其成員變量heap(KeyValueHeap)來(lái)完成必要的操作。heap由多個(gè)StoreFileScanner實(shí)例按照PriorityQueue組成,comparator = CellComparatorImp。

          1.循環(huán)從heap中獲取cell。

          2.通過(guò)matcher匹配cell獲得返回的MatchCode,不同MatchCode會(huì)觸發(fā)不同的操作,見(jiàn)下表。

          MatchCode

          Operation

          INCLUDE

          check

          fill results

          heap.next()

          continue Loop

          INCLUDE_AND_SEEK_NEXT_ROW

          check

          fill results

          seekOrSkipToNextRow

          continue Loop

          INCLUDE_AND_SEEK_NEXT_COL

          check

          fill results

          seekOrSkipToNextColumn

          continue Loop

          DONE

          return results

          DONE_SCAN

          close heap

          return

          SEEK_NEXT_ROW

          if no data: return false;

          else:

          seekOrSkipToNextRow

          continue;

          SEEK_NEXT_COL

          seekOrSkipToNextColumn

          continue;

          SKIP

          heap.next()

          continue Loop

          SEEK_NEXT_USING_HINT

          seekAsDirection

          or heap.next()

          3.不停循環(huán),直到數(shù)據(jù)組成整行,向上返回。

          StoreScanner中KeyValueHeap的next功能:

          storeScanner中的heap.next()究竟做了什么?簡(jiǎn)單來(lái)說(shuō),做了以下兩件事情:1)從current(當(dāng)前的StoreFileScanner,不在heap中)獲取cell返回。2)更新當(dāng)前current,把current放回heap重新排序,再獲取當(dāng)前最優(yōu)先的StoreFileScanner作為current。

          具體做法如下:

          1.從當(dāng)前的StoreFileScanner current中獲取下一個(gè)cell(kvReturn)。再獲取kvReturn往后的第一個(gè)cell(kvNext)

          2.判斷kvNext是否為空。為空代表當(dāng)前current讀取完畢,需要從heap中獲取下一個(gè)scanner記為current。不為空則

          3.從當(dāng)前heap中獲取第一個(gè)scanner,與current 進(jìn)行對(duì)比。判斷它們誰(shuí)通過(guò)peek()獲得的cell key最小,如果scanner更小,那么把current放回heap。重新heap.poll()獲得最新current。

          4.返回kvReturn cell。

          至此整個(gè)HBase的讀路徑分析結(jié)束,留待補(bǔ)充的點(diǎn):

          1.Matcher的實(shí)現(xiàn)邏輯分析。

          2.BloomFilter的過(guò)濾分析。

          3.StoreFileScanner以下直到HDFS之間的鏈路分析,中間涉及一個(gè)BlockCache。

          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲操小逼 | 亚洲无码www | 男人的天堂毛片 | 亚洲欧洲a片 | 国产乱伦视频网站 |