大數據存儲利器 - Hbase 基礎圖解


由於疫情原因在家辦公,導致很長一段時間沒有更新內容,這次終於帶來一篇干貨,是一篇關於 Hbase架構原理 的分享。

 

Hbase 作為實時存儲框架在大數據業務下承擔着舉足輕重的地位,可以說目前絕大多數大數據場景都離不開Hbase。

 

今天就先從 Hbase 基礎入手,來說說 Hbase 經常用到卻容易疏忽的基礎知識。

 

本文主要結構總結如下:

 

 

Hbase 主從架構

Hbase 安裝依靠 Hadoop 與 Zookeeper,網上有很多安裝教程,安裝比較簡單,這里我們就着重看下 Habse 架構,如圖:

 

 

 

 

可以從圖中看出,Hbase 也是主從架構,其中 HMaster 為主,HRegionServer 為從。

 

Zookeeper 主要存儲了Hbase中的元數據信息,如哪個表存儲在哪個 HRegionServer 上;

 

HLog 是作為 Hbase 寫數據前的日志記錄;

 

BLockCache 作為讀寫數據的緩存;

 

HMaster:

 

  • 負責新Region分配到指定HRegionServer

     

  • 管理HRegionServer 間負載均衡,遷移 region

     

  • 當HRegionServer 宕機,負責 region 遷移

 

 

HRegionserver:

 

  • 響應客戶端讀寫請求

     

  • 管理Region

     

  • 切分變大的 Region

 

 

Region:

 

  • 一個 Region 對應一個 Table 表

     

  • Hbase 存儲的最小單元

 

 


 

 

 HBase 表結構

Hbase 列式存儲的結構與行式存儲不同,它的表模型類似下圖:

 

 

表中大致可以分為 rowKey 、列族 、版本號三大元素,列族下可以創建多個列,表中的每一個單元格又稱為 cell,需要注意的是 cell 並不是只有一個數據,它可以有多個版本從而實現在同一rowkey ,同一列族, 同一列下存儲多個數據。

 


 

 

重點來了,有了上面的鋪墊,接下來就可以進入正題部分了 ,下面我們來看下 Hbase 的架構原理。 

 

 

Hbase 架構原理

 

1. Hbase 的存儲原理

    

還回到上邊的架構圖,可以看到 一個 HRegionServer 上有多個 HRegion,一個 Region 實際上就對應了一張表,由於 region 的拆分機制,同一張表的數據可能不會在一個HRegionServer上, 但是一個 Region 肯定只存一張表的數據。

 

下面我們再看看 HRegion 里面的結構:

 

 

 

從圖中我看可以看到以下幾點:

 

  •  一個region包含多個 store,其中 :

 

    • 一個列族就划分成一個 store

       

    • 如果一個表中只有1個列族,那么每一個region中只有一個store

       

    • 如果一個表中只有N個列族,那么每一個region中有N個store

 

 

 

  • 一個store里面只有一個memstore

     

    • memstore 是一塊內存,數據會先寫進 memstore,然后再把數據刷到硬盤

 

 

  • 一個store里面有很多的StoreFile,最后數據以很多 HFile 這種數據結構存在HDFS上

     

    • StoreFile 是 Hfile 的抽象對象,說到StoreFile就等於HFile

       

    • 每次 memsotre 刷新數據到磁盤,就生成對應的一個新的 HFile

 

 

2. Hbase 的讀流程

 

在說讀讀寫流程前,需要說明一下,整個 HBase集群,只有一張meta表(元數據信息表),此表只有一個region,該region數據保存在一個HRegionServer上 。

 

 

  • 1、客戶端首先與zk進行連接;從zk找到meta表的region位置,即meta表的數據存儲在某一HRegionServer上;客戶端與此HRegionServer建立連接,然后讀取meta表中的數據;meta表中存儲了所有用戶表的region信息,我們可以通過scan  'hbase:meta'來查看meta表信息

  • 2、根據要查詢的namespace、表名和rowkey信息。找到寫入數據對應的region信息

  • 3、找到這個region對應的regionServer,然后發送請求

  • 4、查找並定位到對應的region

  • 5、先從memstore查找數據,如果沒有,再從BlockCache上讀取

    • 一部分作為Memstore,主要用來寫;

    • 另外一部分作為BlockCache,主要用於讀數據;

    • HBase上Regionserver的內存分為兩個部分

  • 6、如果BlockCache中也沒有找到,再到StoreFile上進行讀取

    • 從storeFile中讀取到數據之后,不是直接把結果數據返回給客戶端,而是把數據先寫入到BlockCache中,目的是為了加快后續的查詢;然后在返回結果給客戶端。

       

3. Hbase 的寫流程

 

 

  • 1、客戶端首先從zk找到meta表的region位置,然后讀取meta表中的數據,meta表中存儲了用戶表的region信息

  • 2、根據namespace、表名和rowkey信息。找到寫入數據對應的region信息

  • 3、找到這個region對應的regionServer,然后發送請求

  • 4、把數據分別寫到HLog(write ahead log)和memstore各一份

    • write ahead log :也稱為WAL,類似mysql中的binlog,用來做災難恢復時用,HLog記錄數據的所有變更,一旦數據修改,就可以從log中進行恢復。

  • 5、memstore達到閾值后把數據刷到磁盤,生成storeFile文件

  • 6、刪除HLog中的歷史數據

     

4. Hbase 的 flush 與 compact 機制

 

概括來說,flush 是數據由 memstore 刷寫到磁盤的過程,compact 是 磁盤文件合並的過程,如圖所示:

 

 

flush 機制

 

flush 大致可以分為三個階段,prepare 階段,flush 階段,commit 階段:

 

  • prepare 階段

     

 

遍歷當前 Region 中所有的 Memstore,將Memstore中當前數據集CellSkipListSet 做一個快照snapshot,之后創建一個新的CellSkipListSet,后期寫入的數據都會寫入新的CellSkipListSet中

 

  • flush 階段

     

 

遍歷所有Memstore,將 prepare階段生成的 snapshot 持久化為臨時文件,臨時文件會統一放到目錄.tmp下。這個過程因為涉及到磁盤IO操作,因此相對比較耗時

 

  • commit 階段

 

遍歷所有 Memstore,將 flush階段生成的臨時文件移到指定的ColumnFamily目錄下,針對HFile生成對應的storefile和Reader,把storefile添加到HStore的storefiles列表中,最后再清空prepare階段生成的snapshot 

 

flush 的觸發條件一般分為 memstore 級別,region 級別,regionServer 級別,HLog數量上限,具體配置可在官網文檔中查詢到。

 

compact 機制 

 

從圖中可以看出 compact 合並機制,主要分為 小合並 、大合並兩個階段。

 

  • minor compaction 小合並

 

將Store中多個HFile合並為一個HFile,一次Minor Compaction的結果是HFile數量減少並且合並出一個更大的StoreFile,這種合並的觸發頻率很高。

 

 

  • major compaction 大合並

 

合並 Store 中所有的 HFile 為一個HFile,被刪除的數據、TTL過期數據、版本號超過設定版本號的數據。合並頻率比較低,默認7天執行一次,並且性能消耗非常大,建議生產關閉(設置為0),在應用空閑時間手動觸發。一般可以是手動控制進行合並,防止出現在業務高峰期。

 

5. Hbase 的 region 拆分 與 合並

 

region 的拆分

 

Q:

為什么要拆分 region 呢?


A:

region中存儲的是大量的 rowkey 數據 ,當 region 中的數據條數過多, region 變得很大的時候,直接影響查詢效率.因此當 region 過大的時候.hbase會拆分region , 這也是Hbase的一個優點 。



  • region 拆分策略

 

0.94版本前默認切分策略,當region大小大於某個閾值(hbase.hregion.max.filesize=10G)之后就會觸發切分,一個region等分為2個region。

 

0.94版本~2.0版本默認切分策略 :根據拆分次數來判斷觸發拆分的條件

 

region split的計算公式是:

regioncount^3 * 128M * 2,當region達到該 size 的時候進行split

例如:

第一次split:1^3 * 256 = 256MB

第二次split:2^3 * 256 = 2048MB

第三次split:3^3 * 256 = 6912MB

第四次split:4^3 * 256 = 16384MB > 10GB,因此取較小的值10GB

后面每次split的size都是10GB了

 

  • 預分區機制

 

當一個Hbase 表剛被創建的時候,Hbase默認的分配一個 region 給table。也就是說這個時候,所有的讀寫請求都會訪問到同一個 regionServer 的同一個region中,這個時候就達不到負載均衡的效果了,集群中的其他 regionServer 就可能會處於比較空閑的狀態。

 

為了解決這個問題,就有了 pre-splitting,也就是預分區機制,在創建table的時候就配置好,生成多個region,這樣的好處就是可以優化數據讀寫效率;並且使用負載均衡機制,防止數據傾斜。

 

操作很簡單,在創建表時,手動指定分區就好了:

 

create 'person','info1','info2',SPLITS => ['1000','2000','3000','4000']

 

 

region 的合並

 

Region的合並不是為了性能,  而是出於維護的目的 。

 

比如刪除了大量的數據 ,這個時候每個Region都變得很小 ,存儲多個 Region就浪費了 ,這個時候可以把Region合並起來,進而可以減少一些 Region 服務器節點,由此可見 region 的合並其實是為了更好的維護 Hbase 集群。

 

至此,正文內容就結束了,為了更好的梳理這些知識,我將文章中重要的部分都放到下面這張圖中,方便以后總結查閱:

 

 

PS:后續文章更新方向除涉及大數據框架方向外,額外添加 C 語言和數據結構等計算機基礎方向,敬請期待 ~


免責聲明!

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



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