1 層級結構
- Table (HBase 表)
- Region(表的Regions)
- Store(Region中以列族為單位的單元)
- MemStore (用于寫緩存)
- StoreFile (StoreFiles for each Store for each Region for the table)
- Block (讀寫的最小單元)
- StoreFile (StoreFiles for each Store for each Region for the table)
- MemStore (用于寫緩存)
- Store(Region中以列族為單位的單元)
2 重要成員
2.1 Region
Region是HBase數據存儲和管理的基本單位
2.1.1 Region的數量設計
設計的本意是每個Server運行小數量(2-200)個大容量(5-20Gb)的Region,理由如下:
- 每個MemStore需要2MB的堆內存,2MB是配置的,假如有1000擁有兩個列族的Region,那么就需要3.9GB的堆內存,還是沒有存儲任何數據的情況下
- HMaster要花大量的時間來分配和移動Region
- 過多Region會增加ZooKeeper的負擔
- 每個Region會對應一個MapReduce任務,過多Region會產生太多任務
2.1.2 Region的分配
2.1.2.1 啟動時的分配步驟
Master啟動時調用 AssignmentManager。
AssignmentManager 查看hbase:meta中已經分配好的Region
如果Regiond的分配依然有效的話 (如果RegionServer 仍然在線的話) 維持當前分配
如果分配失效,LoadBalancerFactory 會被調用來分配region. 負載均衡器(HBase 1.0默認使用StochasticLoadBalancer ) 分配任務到Region Server中
如果需要的話,Region Server分配信息會更新到hbase:meta中。RegionServer啟動時調用啟動代碼來啟動region。
2.1.2.2 RegionServer失效時的分配步驟
- Region Server掛掉后它上面的regions變得不可用。
- Master檢測到Region Server掛掉了。
- 失效Region Server上的region分配會被認為無效并采用跟啟動時同樣順序的步驟分配region
- 正在進行的查詢操作會重新執行,不會丟失
- 切換動作要在以下時間內完成:
ZooKeeper session timeout + split time + assignment/replay time
2.1.3 Region的位置選擇
Region的位置選擇通過HDFS的復制機制完成
1)步驟:
- 第一個副本寫在本地節點
- 第二副本寫到另一個機上任意節點
- 第三個副本寫到跟第二副本相同機架不同節點的其他節點
- 后面的副本將寫到集群中的任意節點中。
2)要點:
- 選址是在flush或者compaction之后執行的
- 當RegionServer失效后,其上的Region被轉移到其他的RegionServer,那么此時被轉移的Region不具備數據本地性,直到下一次compaction執行之后才重新具備數據本地性
2.1.4 Region的切分
- 當Region的大小達到指定的閥值時,RegionServer會執行Region的切分
- 該操作有RegionServer單獨執行,Master不參與
- 分裂執行完畢后,會將子Region添加到hbase:meta并且匯報給Master
- 可以自定義切分策略,可以在hbase-site.xml設置
<property>
<name>hbase.regionserver.region.split.policy</name>
<value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>
- 支持手動執行切分
- 可以指定切分點
2.1.5 Region的合并
2.1.5.1 意義
- 當存在大量沒有數據的region時,執行region的合并來避免region過多
- 之所以會存在大量沒有數據的region是因為為了避免region到達閥值引起分裂的開銷,創建表格時先進行預分區。
2.1.5.2 步驟
- 客戶端發送指令給Master
- Master收到指令后將要合并的region移動到指定的RegionServer
- Master發送Merge請求給指定的RegionServer執行合并操作
- 最后將被合并的regions從hbase:meta中刪除并添加合并后的region
2.2 Store
- 以列族為單元,即對應表中每個region中一個列族
- 包含一個MemStore和0到多個StoreFile(HFile)
2.2.1 MemStore
- 將修改信息緩存在內存當中
- 信息格式為Cell/KeyValue
- 當flush觸發時,MemStore會生成快照保存起來,新的MemStore會繼續接收修改信息,指導flush完成之后快照會被刪除
- 當一個MemStore flush發生時,屬于同一個region的memStore會一起flush
2.2.2.1 MemStore Flush的觸發情況
- MemStore的大小達到單個MemStore閥值
- RegionServer中所有MemStore的使用率超過RS中MemStore上限值,該Server上所有MemStore會執行flush直到完成或者小于RS中MemStore安全值
- RegionServer中WAL超過WAL閥值
單個MemStore閥值:hbase.hregion.memstore.flush.size
RS中MemStore上限值:hbase.regionserver.global.memstore.upperLimit
RS中MemStore安全值:hbase.regionserver.global.memstore.lowerLimit
WAL閥值:hbase.regionserver.max.logs
2.3 StoreFile/HFile
2.3.1 格式
2.3.1.1 概念:
- Data Block Size:數據塊大小。默認為64KB。因為查詢key是按照順序查詢的,所以需要選擇合適的Size來避免一個Block包含過多Key/Value對。
- Maximum Key Length:最大key長度。10-100字節是比較合適的大小,key的形式:rowkey+column family:qualifier+timestamp
- Maximum File Size:最大File大小。Trailer、File-Info和Data-Index都會在讀取和寫入時存到內存中,所以最好保證File的大小在合理的范圍,避免占用過多內存。
- Compression Algorithm:壓縮算法。
- 好處:
- 減少磁盤I/O
- 提高傳輸效率和減少磁盤空間
- 減少讀取請求的返回量
- 支持的壓縮庫
- GZ
- LZO
2.3.1.2 HFile 結構
結構圖如下:
- Data Block:存儲鍵值對的長度和值
- Meta Block:用戶定義元數據
- File Info:關于HFile的元數據
- Data Index:Data Block的索引,也就是每個Block的第一個Key的偏移量
- Trailer:固定的源數據,用于存儲以上每個部分的偏移量,讀取HFile時首先要讀取Trailer。
2.3.2 KeyValue
KeyValue以字節數組的形式存儲,包含以下部分:
- keylength
- valuelength
- key
- value
Key的格式如下:
- rowlength
- row (也就是the rowkey)
- columnfamilylength
- columnfamily
- columnqualifier
- timestamp
- keytype (例如 Put, Delete, DeleteColumn, DeleteFamily)
2.4 Scan 步驟
- 當客戶端提交scan請求時,HBase會創建為每個Region創建RegionScanner 實例來處理scan請求
- RegionScanner 包含一組StoreScanner實例,每個列族對應一個StoreScanner實例
- 每個StoreScanner實例包含一組StoreFileScanner實例, 每個toreFileScanner實例對應每個列族的HFile, 同時包含一組對應MemStore的KeyValueScanner。
- The two lists are merged into one, which is sorted in ascending order with the scan object for the MemStore at the end of the list.
- 當StoreFileScanner實例被構造, 會生成MultiVersionConcurrencyControl 讀取點, 就是當前的memstoreTS, 用來過濾掉
2.5 Compaction
2.5.1 Minor Compaction(次壓縮)
HBase會自動挑選小的臨近的HFiles將它們重新寫到一些大的HFiles中。這個過程稱為次壓縮。次壓縮通過將更小的files寫到一些大的flies進行合并操作來實現減少file的數量。
2.5.2 Major Compaction(主壓縮)
- 合并一個Region中每一個列族的所有HFile寫到一個HFile中
- 會刪除掉那些標記刪除和過期的cells。提高了讀取性能
- 將所有數據進行了重寫,產生大量的I/O開銷或者網絡開銷,稱為寫放大
- 自動執行,通常安排在周末或者晚上
2.6 Region 負載均衡
當region分裂之后,RS之間的region數量差距變大時,HMaster便會執行負載均衡來調整部分region的位置,使得每個RS的region數量保持在合理范圍之內,負載均衡會引起region的重新定位,使得涉及的region不具備數據本地性,即HFile和region不在同一個DataNode。這種情況會在major compaction 之后得到解決。
參考文章:
HFile: A Block-Indexed File Format to Store Sorted Key-Value Pairs
Apache HBase ? Reference Guide
An In-Depth Look at the HBase Architecture
若有侵權,請聯系我。