HBase的Compact參數設置及數據讀寫流程剖析-OLAP商業環境實戰

本套系列博客從真實商業環境抽取案例進行總結和分享,並給出Spark商業應用實戰指導,請持續關注本套博客。版權聲明:本套Spark商業應用實戰歸做者(秦凱新)全部,禁止轉載,歡迎學習。shell

1 前言

Hbase適合存儲PB級別的海量數據,在PB級別的數據以及採用廉價PC存儲的狀況下,能在幾十到百毫秒內返回數據。這與Hbase的極易擴展性息息相關。正由於Hbase良好的擴展性,才爲海量數據的存儲提供了便利。根據Google的Chang等人發表的論文數據庫

Bigtable:A Distributed Storage System for Strctured Data
複製代碼

來設計的。整體架構以下:架構

2010年5月,Hbase從Hadoop子項目升級成Apache頂級項目。簡而言之:HBase是一個經過大量廉價的機器解決海量數據的高速存儲和讀取的分佈式數據庫解決方案。一圖歸納以下所示:併發

1.1 HBase 如何基於LSM樹作索引

順序寫只是把動做寫到磁盤上了,只有compact後纔是真正的數據。

2 HBase 讀寫數據過程

2.1 HBase 寫數據過程

  • 先將數據寫到WAL中;
  • WAL 存放在HDFS之上;
  • 每次Put、Delete操做的數據均追加到WAL末端;
  • 持久化到WAL以後,再寫到MemStore中;
  • 二者寫完返回ACK到客戶端。

2.2 HBase 內存結構

MemStore 實際上是一種內存結構,一個Column Family 對應一個MemStore 分佈式

2.3 HBase 讀數據過程 (0.96版本之前)

  • 第1步:client請求ZK得到-ROOT-所在的RegionServer地址高併發

  • 第2步:client請求-ROOT-所在的RS地址,獲取.META.表的地址,client會將-ROOT-的相關信息cache下來,以便下一次快速訪問oop

  • 第3步:client請求 .META.表的RS地址,獲取訪問數據所在RegionServer的地址,client會將.META.的相關信息cache下來,以便下一次快速訪問post

  • 第4步:client請求訪問數據所在RegionServer的地址,獲取對應的數據性能

2.4 HBase 讀數據過程 (0.96版本之後)

  • 第1步:Client請求ZK獲取.META.所在的RegionServer的地址。學習

  • 第2步:Client請求.META.所在的RegionServer獲取訪問數據所在的RegionServer地址,client會將.META.的相關信息cache下來,以便下一次快速訪問。

  • 第3步:Client請求數據所在的RegionServer,獲取所須要的數據。

2.5 HBase 去掉-ROOT-的緣由

  • 其一:提升性能

  • 其二:2層結構已經足以知足集羣的需求

3 HBase Compact 功能剖析

Compaction會從一個region的一個store中選擇一些hfile文件進行合併。合併說來原理很簡單,先從這些待合併的數據文件中讀出KeyValues,再按照由小到大排列後寫入一個新的文件中。以後,這個新生成的文件就會取代以前待合併的全部文件對外提供服務。HBase根據合併規模將Compaction分爲了兩類:MinorCompaction和MajorCompaction

  • Minor Compaction是指選取一些小的、相鄰的StoreFile將他們合併成一個更大的StoreFile,在這個過程當中不會處理已經Deleted或Expired的Cell。一次Minor Compaction的結果是更少而且更大的StoreFile。

  • Major Compaction是指將全部的StoreFile合併成一個StoreFile,這個過程還會清理三類無心義數據:被刪除的數據、TTL過時數據、版本號超過設定版本號的數據。另外,通常狀況下,Major Compaction時間會持續比較長,整個過程會消耗大量系統資源,對上層業務有比較大的影響。所以線上業務都會將關閉自動觸發Major Compaction功能,改成手動在業務低峯期觸發。

  • 下列三個條件可能會觸發compaction請求:

    1. memstore flush以後觸發;

    2. 客戶端經過shell或者API觸發;

    3. 後臺線程CompactionChecker按期觸發,週期爲:

      hbase.server.thread.wakefrequency*hbase.server.compactchecker.interval.multiplier。
      複製代碼
    4. 對於MajorCompact,觸發了compaction請求後,真正的compaction操做可否執行,還要進行一系列的條件驗證, 即由hbase.hregion.majorcompaction和hbase.hregion.majorcompaction.jitter控制的一組條件。

    5. 對於MiniCompact當文件大小小於hbase.hstore.compaction.min.size 則會當即被添加到合併隊列,當storeFile數量超過hbase.hstore.compaction.min時,minor compaction纔會啓動。

1.1 Hbase MinorCompact 參數設置

hbase.hregion.memstore.flush.size:640M
hbase.hregion.max.filesize  :100M  觸發split
hbase.hstore.compaction.min : 知足條件 3 minor compaction纔會啓動
hbase.hstore.compaction.ratio :默認爲1.2
hbase.hregion.majorcompaction : 0 關掉major compact
hbase.hstore.compaction.max : 默認值爲10,表示一次minor compaction中最多選取10個store file
hbase.hstore.compaction.min : 默認值爲 3
hbase.hstore.compaction.min.size :640M (未壓縮?爲memestoreFlushSize)
複製代碼
  • hbase.hstore.compaction.ratio :默認爲1.2 ,將store file 按照文件年齡排序(older to younger),minor compaction老是從older store file開始選擇,若是該文件的size 小於它後面hbase.hstore.compaction.max 個store file size 之和乘以 該ratio,則該store file 也將加入到minor compaction 中。

  • hbase.hstore.blockingStoreFiles:HStore的storeFile的文件數大於配置值,則在flush memstore前先進行split或者compact,除非超過hbase.hstore.blockingWaitTime配置的時間,默認爲7,可調大,好比:100,避免memstore不及時flush,當寫入量大時,觸發memstore的block,從而阻塞寫操做。

  • hbase.hregion.max.filesize :默認值是256M 當hbase.hregion.max.filesize比較小時,觸發split的機率更大,而split的時候會將region offline,所以在split結束的時間前,訪問該region的請求將被block住,客戶端自我block的時間默認爲1s。當大量的region同時發生split時,系統的總體訪問服務將大受影響。所以容易出現吞吐量及響應時間的不穩定現象

  • hbase.hregion.max.filesize : 當hbase.hregion.max.filesize比較大時,單個region中觸發split的機率較小,大量region同時觸發split的機率也較小,所以吞吐量較之小hfile尺寸更加穩定些。可是因爲長期得不到split,所以同一個region內發生屢次compaction的機會增長了。compaction的原理是將原有數據讀一遍並重寫一遍到hdfs上,而後再刪除原有數據。無疑這種行爲會下降以io爲瓶頸的系統的速度,所以平均吞吐量會受到一些影響而降低

  • hbase.hregion.max.filesize 這個值過大,讀寫hbase的速度會變慢,由於底層對hdfs的讀寫操做因爲文件數量少,很難作到高併發,高吞吐,太小會發生頻繁的文件split,split過程會使數據短暫離線,會對數據的訪問有必定影響,不太穩定,因此這個值不能過小也不能太大,100-200MB基本能知足需求

  • 基於文件大小進行合併

    hbase.hstore.compaction.min.size 表示文件大小小於該值的store file 必定會加入到minor compaction的store file中
      hbase.hstore.compaction.max.size Long.MAX_VALUE  表示文件大小大於該值的store file 必定會被minor compaction排除
    複製代碼
  • 基於文件數量進行合併

    hbase.hstore.compaction.min :默認值爲 3,表示至少須要三個知足條件的store file時,minor compaction纔會啓動
      hbase.hstore.compaction.max :默認值爲10,表示一次minor compaction中最多選取10個store file
    複製代碼
  • hbase.hstore.blockingWaitTime block的等待時間 線上配置:90000(90s) 默認配置:90000(90s)

  • hbase.regionserver.global.memstore.upperLimit,默認爲整個heap內存的40%。但這並不意味着全局內存觸發的刷盤操做會將全部的MemStore都進行輸盤,而是經過另一個參數hbase.regionserver.global.memstore.lowerLimit來控制,默認是整個heap內存的35%。當flush到全部memstore佔整個heap內存的比率爲35%的時候,就中止刷盤。這麼作主要是爲了減小刷盤對業務帶來的影響,實現平滑系統負載的目的。

  • hbase.hregion.memstore.flush.size:當MemStore的大小達到hbase.hregion.memstore.flush.size大小的時候會觸發刷盤,默認128M大小。

  • hase.regionserver.max.logs :前面說到Hlog爲了保證Hbase數據的一致性,那麼若是Hlog太多的話,會致使故障恢復的時間太長,所以Hbase會對Hlog的最大個數作限制。當達到Hlog的最大個數的時候,會強制刷盤。這個參數是hase.regionserver.max.logs,默認是32個。

1.2 Hbase MinorCompact 功能

爲了本文的主題,此處參考了一篇很是好的博客,僅限該小節:https://blog.csdn.net/u014297175/article/details/50456147
複製代碼
  • 刷入一個54.4M的文件,在此觸發一次Minor合併。從最先的文件,66.5G的開始,它顯然比它後面幾個文件(按配置是10個文件Ratio的大小),但他後面本不足10個文件,所以直接計入全部文件大小總和1.2。顯然,它的大小超過了這個值,所以不歸入Minor合併,同理一直到666.4M文件,它也不小於54.3M*1.2因此不歸入合併,所以這波參與合併的只有54.3M文件,暫且等待下一個刷寫文件。

  • 刷入一個54M的文件,這時進入合併流程,由於hbase.hstore.compaction.min=3,兩個54M文件並未參與到合併。

  • 最後刷入一個54M的文件,3個54M文件合併成爲一個150M的文件,其實這是3個54M一塊兒合併的文件。可是那個666.4M的文件仍然不能歸入合併隊列。

注意:後面會不斷判斷進行Older to younger 的合併,可是這個154M的文件會歸入合併隊列,由於當文件大小小於
         hbase.hstore.compaction.min.size(爲memestoreFlushSize) 則會當即被添加到合併隊列。
複製代碼

1.2 Hbase MajorCompact 參數設置

MajorCompact 條件:

  • hbase.hregion.majorcompaction:默認是24小時 hbase.hregion.majorcompaction.jitter:抖動,默認是20% 以上兩個參數意味着major合併週期爲隨機取19.2小時~28.8小時之間的數值。當major合併週期還未到達時,執行minor合併。

1.3 split 參數設置

一個reion達到必定的大小,他會自動split稱兩個region。若是咱們的Hbase版本是0.94 ,那麼默認的有三種自動split的策略,ConstantSizeRegionSplitPolicy,IncreasingToUpperBoundRegionSplitPolicy還有 KeyPrefixRegionSplitPolicy.

1.4 Hlog的生命週期設置

  • hbase.regionserver.logroll.period :Hlog的大小經過參數hbase.regionserver.logroll.period控制,默認是1個小時,時間達到hbase.regionserver.logroll.period 設置的時間,Hbase會建立一個新的Hlog文件。這就實現了Hlog滾動的目的。
  • hbase.regionserver.maxlogs:Hbase經過hbase.regionserver.maxlogs參數控制Hlog的個數。滾動的目的,爲了控制單個Hlog文件過大的狀況,方便後續的過時和刪除。

2 MVCC 多版本控制

目前Hbase僅支持行級事務,不支持跨行跨表事務要求。

2.1 HBase事務的強一致性保證

  • 寫寫併發控制
  • 批量寫入多行的寫寫併發控制
  • 讀寫併發控制

2.2 WAL日誌的原子性

2.3 寫寫併發控制,存在前後順序:

提供一個基於行的獨佔鎖來保證對同一行寫的獨立性,因此寫的順序是:

  • 獲取行鎖
  • 寫WAL文件
  • 更新MemStore:將每一個Cell寫入到memstore
  • 釋放行鎖

2.4 批量寫入多行的寫寫併發控制

兩階段鎖協議:不是一行一行的得到鎖,批量寫多行場景,防止死鎖場景 兩階段鎖協議,過程以下:

  • 獲取全部待寫入(更新)行記錄的行鎖。
  • 開始執行寫入(更新)操做
  • 寫入完成以後再統一釋放全部行記錄的行鎖。

兩階段鎖協議:不是一行一行的得到鎖,而是批量寫多行場景,防止多個事務之間造成死鎖場景。

2.5 讀寫併發控制

經過事務序列來控制順序: 事務只有提交了纔會出列,經過指針(Read Point)指到底部已提交事務號,指針之下的用戶才能可見:

3 總結

還須要進一步完善Major Compact的腳本控制邏輯

秦凱新 於深圳

相關文章
相關標籤/搜索