HBase 架構與工做原理3 - HBase 讀寫與刪除原理

本文系轉載,若有侵權,請聯繫我:likui0913@gmail.comhtml

1、前言

在 HBase 中,Region 是有效性和分佈的基本單位,這一般也是咱們在維護時能直接操做的最小單位。好比當一個集羣的存儲在各個節點不均衡時,HMaster 即是經過移動 Region 來達到集羣的平衡。或者某一個 Region 的請求太高時,經過分裂 Region 來分散請求。或者咱們能夠指定 Region 的 startKey 和 endKey 來設計它的數據存放範圍等等。apache

因此,HBase 在讀寫數據時,都須要先找到對應的 Region,而後再經過具體的 Region 進行實際的數據讀寫。緩存

目錄表(Catalog Tables)

客戶端在訪問 Region 中的數據以前,須要先經過 HMaster 肯定 Region 的位置,而 HMaster 則將全部 Region 的元信息都保存在 hbase:meta 中。服務器

hbase:meta

Meta 表是一個特殊的 HBase 表,它保存了集羣中全部 Region 的列表,它的地址被存儲在 Zookeeper 中。其表結構以下:數據結構

- RowKey:
    - Region Key 格式([table],[region start key],[region id])
- Values:
    - info:regionInfo (序列化的.META.的HRegionInfo實例)
    - info:server(保存.META.的RegionServer的server:port)
    - info:serverStartCode(保存.META.的RegionServer進程的啓動時間)

根據 Meta 表中的數據,能夠肯定客戶端所訪問的 RowKey 所處的實際位置。ide

META table

2、讀取與緩存元數據(首次讀取或寫入)

客戶端第一次讀取或寫入 HBase 時將發生如下步驟:性能

1) 客戶端從 Zookeeper 獲取存儲 META 表的 Region 服務器地址; 2) 客戶端查詢 META 表所在服務器來獲取與想要訪問的行鍵相對應的 RegionServer 地址,而後客戶端將這些信息與 META 表位置一塊兒緩存; 3) 客戶端從對應的 RegionServer 獲取指定行;ui

對於以後的讀取,客戶端使用緩存的信息來檢索 META 的位置和已經讀取過的行鍵位置信息。隨着時間的推移,它將不須要查詢 META 表,直到因爲某個 Region 已經移動或丟失,客戶端纔會從新查詢並更新緩存。spa

write and read first

3、HBase 寫入原理

在初次讀取寫入時,客戶端已經緩存了 META 表的信息,同時由於在 HBase 中數據是按行鍵有序排列的,因此客戶端能過經過將要寫入數據的行鍵和緩存信息直接找到對應的 RegionServer 和 Region 位置。那麼當客戶端發出 Put 請求直到數據真正寫入磁盤,它將主要通過如下步驟:設計

1) 將數據寫入預寫日誌 WAL 2) 寫入並排序 MemStore 緩存數據 3) 刷新緩存中的數據,並寫入到 HFile磁盤

1. 將數據寫入預寫日誌 WAL

當客戶端發出 Put 請求時,HBase 首先會將數據寫入預寫日誌:

  • 編輯 WAL 文件,將數據附加到 WAL 文件的末尾(知足 HDFS 只容許追加的特性);
  • 若是服務器崩潰,那麼將經過 WAL 文件恢復還沒有保存的數據;

write WAL

2. 寫入並排序 MemStore 緩存數據

一旦數據寫入 WAL 成功後,數據將被放入 MemStore 中,而後將 Put 請求確認返回給客戶端。客戶端接收到確認信息後,對於客戶端來講,這次操做便結束了。

寫入並排序 MemStore 緩存數據

數據放入 MemStore 中後,HBase 不會當即刷新數據到磁盤,而是先更新存儲數據使其做爲有序的 KeyValues 結構,與存儲在 HFile 中的結構相同,並等待 MemStore 累積到足夠的數據時纔會刷新數據以寫入磁盤。

寫入並排序 MemStore 緩存數據

3. 刷新緩存中的數據,並寫入到 HFile磁盤

當 MemStore 累積到足夠的數據時,整個有序的數據集將被寫入 HDFS 中的一個新的 HFile 文件。至此,客戶端從發出 Put 請求到數據持久化的過程纔算是真正的完成。

可能影響性能的因素

  • 由於每個列族都有一個 MemStore,而當發生刷新時,屬於同一個 Region 下的全部 MemStore 都將刷新,這可能致使性能降低,並影響最終的 HFile 文件大小(HDFS 不適合存儲小文件),因此列族的數量應該被限制以提升總體效率。

4、HBase 讀取原理

根據 HBase 的 RegionServers 的結構可知:在 HBase 中,與一行數據相對應的 KeyValue 單元格可能位於多個位置,好比:行單元格(row cells)已經保存在 HFiles 中,最近更新的單元格位於 MemStore 中,最近讀取的單元格位於 BlockCache 中。因此當客戶端讀取一行數據時,HBase 須要將這些數據合併以獲得最新的值。

讀取合併

HBase 將經過如下步驟來合併 BlockCache、MemStore 和 HFile 中的數據:

1) 首先,掃描程序查找 BlockCache 中的行單元格(讀取緩存)。最近讀取的 keyValue 被緩存在這裏,而且當須要使用內存時,清除掉最近使用最少的數據; 2) 而後,掃描器在 MemStore 中查找包含最近寫入內存中的緩存數據; 3) 若是掃描器在 MemStore 和 BlockCache 中沒有找到全部的行單元格,HBase 將使用 BlockCache 索引和 Bloom 過濾器將 HFile 加載到內存中,它可能包含目標行單元格。

注:Bloom 過濾器肯定的結果並不必定老是準確的,可是否認的結果卻必定保證準確。

Merge

可能影響性能的因素

  • 刷新數據時,一個 MemStore 可能會產生多個相同的 HFile 文件(爲何會產生多個相同的文件?),這意味着讀取時可能須要檢查多個文件,這可能會影響性能。這種行爲被稱爲讀取放大;
  • 客戶端使用掃描全表數據操做時,可能會檢查更多的文件,因此不建議使用掃描全表操做;

5、HBase 刪除原理

HBase 的刪除操做並不會當即將數據從磁盤上刪除,這主要是由於 HBase 的數據一般被保存在 HDFS 之中,而 HDFS 只容許新增或者追加數據文件,因此刪除操做主要是對要被刪除的數據打上標記。

HFile 中保存了已經排序過的 KeyValue 數據,KeyValue 類的數據結構以下:

{ keylength, valuelength, key: { rowLength, row (i.e., the rowkey), columnfamilylength, columnfamily, columnqualifier, timestamp, keytype (e.g., Put, Delete, DeleteColumn, DeleteFamily) } value 

當執行刪除操做時,HBase 新插入一條相同的 KeyValue 數據,可是使 keytype=Delete,這便意味着數據被刪除了,直到發生 Major_compaction 操做時,數據纔會被真正的從磁盤上刪除。

參考連接

相關文章
相關標籤/搜索