本文系轉載,若有侵權,請聯繫我:likui0913@gmail.comhtml
在 HBase 中,Region 是有效性和分佈的基本單位,這一般也是咱們在維護時能直接操做的最小單位。好比當一個集羣的存儲在各個節點不均衡時,HMaster 即是經過移動 Region 來達到集羣的平衡。或者某一個 Region 的請求太高時,經過分裂 Region 來分散請求。或者咱們能夠指定 Region 的 startKey 和 endKey 來設計它的數據存放範圍等等。apache
因此,HBase 在讀寫數據時,都須要先找到對應的 Region,而後再經過具體的 Region 進行實際的數據讀寫。緩存
客戶端在訪問 Region 中的數據以前,須要先經過 HMaster 肯定 Region 的位置,而 HMaster 則將全部 Region 的元信息都保存在 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
客戶端第一次讀取或寫入 HBase 時將發生如下步驟:性能
1) 客戶端從 Zookeeper 獲取存儲 META 表的 Region 服務器地址; 2) 客戶端查詢 META 表所在服務器來獲取與想要訪問的行鍵相對應的 RegionServer 地址,而後客戶端將這些信息與 META 表位置一塊兒緩存; 3) 客戶端從對應的 RegionServer 獲取指定行;ui
對於以後的讀取,客戶端使用緩存的信息來檢索 META 的位置和已經讀取過的行鍵位置信息。隨着時間的推移,它將不須要查詢 META 表,直到因爲某個 Region 已經移動或丟失,客戶端纔會從新查詢並更新緩存。spa
在初次讀取寫入時,客戶端已經緩存了 META 表的信息,同時由於在 HBase 中數據是按行鍵有序排列的,因此客戶端能過經過將要寫入數據的行鍵和緩存信息直接找到對應的 RegionServer 和 Region 位置。那麼當客戶端發出 Put 請求直到數據真正寫入磁盤,它將主要通過如下步驟:設計
1) 將數據寫入預寫日誌 WAL 2) 寫入並排序 MemStore 緩存數據 3) 刷新緩存中的數據,並寫入到 HFile磁盤
當客戶端發出 Put 請求時,HBase 首先會將數據寫入預寫日誌:
一旦數據寫入 WAL 成功後,數據將被放入 MemStore 中,而後將 Put 請求確認返回給客戶端。客戶端接收到確認信息後,對於客戶端來講,這次操做便結束了。
數據放入 MemStore 中後,HBase 不會當即刷新數據到磁盤,而是先更新存儲數據使其做爲有序的 KeyValues 結構,與存儲在 HFile 中的結構相同,並等待 MemStore 累積到足夠的數據時纔會刷新數據以寫入磁盤。
當 MemStore 累積到足夠的數據時,整個有序的數據集將被寫入 HDFS 中的一個新的 HFile 文件。至此,客戶端從發出 Put 請求到數據持久化的過程纔算是真正的完成。
根據 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 過濾器肯定的結果並不必定老是準確的,可是否認的結果卻必定保證準確。
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 操做時,數據纔會被真正的從磁盤上刪除。