hbase實踐之HFile結構


本文目錄如下所示:

目錄

  • HFile在HBase架構中的位置
  • 什么是HFile
  • HFile邏輯結構
  • HFile邏輯結構的優點
  • HFile物理結構
  • HFile生成流程
  • HFile中Block塊解析
  • 多大的HFile文件才存在Intermiate Index Block

HFile在HBase架構中的位置

image

如上圖所示,HFile是HBase最底層的文件組織形式。

Table
    --N Region
        --N Store
            --N StoreFile
                --HFile(StoreFile與HFile是一對一)

什么是HFile

HFile是HBase存儲數據的文件組織形式,參考BigTable的SSTable和Hadoop的TFile實現。

從HBase開始到現在,HFile經歷了三個版本,其中V2在0.92引入,V3在0.98引入。HFileV1版本的在實際使用過程中發現它占用內存多,HFile V2版本針對此進行了優化,HFileV3版本基本和V2版本相同,只是在cell層面添加了Tag數組的支持。鑒於此,本文主要針對V2版本進行分析。

HFile邏輯結構

最初的HFile格式(HFile V1)

image

Data Block默認大小為64k。

Data Index部分存儲了每一個Data Block的索引信息{Offset,Size,FirstKey},這里只有1級索引,當HFile較大,索引信息過多,導致一個RegionServer啟動時可能需要加載數GB的Data Block Index數據。這在一個大數據量的集群中,幾乎無法忍受。另外,第一次讀取時需要加載所有的Bloom Filter數據到內存中。一個HFile中的Bloom Filter的數據大小可達百MB級別。

Data Block Index究竟有多大?
一個Data Block在Data Block Index中的索引信息包含{Offset, Size, FirstKey},BlockOffset使用Long型數字表示,Size使用Int表示即可。假設用戶數據RowKey的長度為50bytes,那么,一個64KB的Data Block在Data Block Index中的一條索引數據大小約為62字節。

假設一個RegionServer中有500個Region,每一個Region的數量為10GB(假設這是Data Blocks的總大小),在這個RegionServer上,約有81920000個Data Blocks,此時,Data Block Index所占用的大小為81920000*62bytes,約為4.7GB

HFile V2設計

作為V1的改進版,V2解決了此前存在的問題。

image

文件主要分為四個部分:Scanned block section,Non-scanned block section,Opening-time data section和Trailer。

Scanned block section:顧名思義,表示順序掃描HFile時所有的數據塊將會被讀取,包括Leaf Index Block和Bloom Block。

Non-scanned block section:表示在HFile順序掃描的時候數據不會被讀取,主要包括Meta Block和Intermediate Level Data Index Blocks兩部分。

Load-on-open-section:這部分數據在HBase的region server啟動時,需要加載到內存中。包括FileInfo、Bloom filter block、data block index和meta block index。

Trailer:這部分主要記錄了HFile的基本信息、各個部分的偏移值和尋址信息。

HFile邏輯結構的優點

  1. 分層索引
    Data Block的索引,在HFile V2中最多可支持三層索引:
  • Root Data Index
    • Intermediate Index Block
      • Leaf Index Block
        • Data Block
  1. 交叉存放

在”Scanned Block Section“區域,Data Block(存放用戶數據KeyValue)、存放Data Block索引的Leaf Index Block(存放Data Block的索引)與Bloom Block(Bloom Filter數據)交叉存在。

  1. 按需讀取
    無論是Data Block的索引數據,還是Bloom Filter數據,都被拆成了多個Block,基於這樣的設計,無論是索引數據,還是Bloom Filter,都可以按需讀取,避免在Region Open階段或讀取階段一次讀入大量的數據,有效降低時延。

將索引分級后,RegionServer不需要將所有索引都加載,加載一級索引即可。

HFile物理結構

  • 所有block塊都擁有相同的數據結構,如圖左側所示,HBase將block塊抽象為一個統一的HFileBlock。HFileBlock支持兩種類型,一種類型不支持checksum,一種不支持。
    image

  • 不支持checksum的HFileBlock內部結構:
    image

HFileBlock主要包括兩部分:BlockHeader和BlockData。其中BlockHeader主要存儲block元數據,BlockData用來存儲具體數據。

block元數據中最核心的字段是BlockType字段,用來標示該block塊的類型,HBase中定義了8種BlockType,每種BlockType對應的block都存儲不同的數據內容,有的存儲用戶數據,有的存儲索引數據,有的存儲meta元數據。對於任意一種類型的HFileBlock,都擁有相同結構的BlockHeader,但是BlockData結構卻不相同。

  • 每種BlockType進行詳細的講解:

image

HFile中Block塊解析

image

image

HFile生成流程

基本思路:先填滿內容,再生成header,最后生成checksum之類。

起初,HFile中並沒有任何Block,數據還存在於MemStore中。

Flush發生時,創建HFile Writer,第一個空的Data Block出現,初始化后的Data Block中為Header部分預留了空間,Header部分用來存放一個Data Block的元數據信息。

而后,位於MemStore中的KeyValues被一個個append到位於內存中的第一個Data Block中:

image

image

  • Header內容
    image

image

為輸出的Data Block生成一條索引記錄,包含這個Data Block的{起始Key,偏移,大小}信息,這條索引記錄被暫時記錄到內存的Block Index Chunk中:

image

Leaf Index Block:

image

image

image

image

image

  • Bloom Filter
    image

多大的HFile文件才存在Intermiate Index Block

基於每一個Block中的FirstKey為50bytes的假設,一個128KB的Root Index Block可容納的HFile文件總大小約為252GB。

如果實際的RowKey小於50 Bytes,或者將Data Block的Size調大,一個128KB的Root Index Chunk所關聯的HFile文件將會更大。因此,在大多數場景中,Intermediate Index Block並不會存在。

總結

關於架構設計的一些基本思想在HFile中得到充分體現,分治(HFile本身屬於分治的產物,Table的存儲被分解成HFile的存儲)、HFileBlock的抽象,分層(索引),架構演進(v1/v2/v3的演進)。

另外HFileBlock數據結構設計比較好,支持8種結構。

參考文獻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM