hbase實踐之flush and compaction

本文主要涉及flush流程,探討flush流程過程當中引入的問題並闡述2種解決策略,最後簡要說明Flush執行策略。sql

對於Compaction,本文主要探討Compaction要解決的本質問題以及由Compaction引入的問題。面對Compaction帶來的雙刃劍,如何根據本身的業務模型合理的執行Compaciton,不一樣的場景能夠採用不一樣的Compaction策略以及如何選擇待合併文件。nosql

Flush

1. Flush流程(HBase 1.*)
MemStore中的數據,達到必定的閾值,被Flush成HDFS中的HFile文件。

2. 由Flush流程而引入的問題

隨着Flush次數的不斷增多,HFile的文件數量也會不斷增多,那這會帶來什麼影響?性能

image

Hontonworks測試過的隨着HFile的數量的不斷增多對讀取時延帶來的影響如上圖所示,隨着HFile文件增多,讀取延時增大。由於查詢一條記錄須要讀取1~N個HFile文件,文件越多,N越大,讀取時間開銷越大。測試

針對上述問題,能夠減小HFile文件的數量減小讀取延時,有2種解決思路:插件

  • 經過compation減小HFile
  • 在內存中執行一部分compaction操做,即HBase2.0中的改進。code

    3. Flush流程(HBase 2.0)

    image

MemStore由一個可寫的Segment,以及一個或多個不可寫的Segments構成。blog

將一部分合並工做上移到內存。減小Hfile生成數量(4次-->1次),減小寫的次數。改善IO放大問題。頻繁的Compaction對IO資源的搶佔,其實也是致使HBase查詢時延大毛刺的罪魁禍首之一教程

  • 那爲什麼不乾脆調大MemStore的大小?這裏的本質緣由在於,ConcurrentSkipListMap在存儲的數據量達到必定大小之後,寫入性能將會出現顯著的惡化。

在融入了In-Memory Flush and Compaction特性以後,Flush與Compaction的總體流程演變爲:圖片

image

4. Flush執行策略

一個Region中是否執行Flush,原來的默認行爲是經過計算Region中全部Column Family的總體大小,若是超過了一個閾值,則這個Region中全部的Column Family都會被執行Flush。ip

而2.0版本中默認啓用的Flush策略爲FlushAllLargeStoresPolicy,也就是說,這個策略使得每一次 只Flush超出閾值大小的Column Family,若是都未超出大小,則全部的Column Family都會被Flush。

改動以前,一個Region中全部的Column Family的Flush都是同步的,雖然容易致使大量的小HFile,但也有好處,尤爲是對於WAL文件的快速老化,避免致使過多的WAL文件。而若是這些Column Family的Flush不一樣步之後,可能會致使過多的WAL文件(過多的WAL文件會觸發一些擁有老數據的Column Family執行Flush)。

Compaction

小範圍的HFile文件合併,稱之爲Minor Compaction,一個列族中將全部的HFile文件合併,稱之爲Major Compaction。

1. HBase Compaction要解決的本質問題是什麼?

減小HFile文件數量,減小文件句柄數量,下降讀取時延

Major Compaction能夠幫助清理集羣中再也不須要的數據(過時數據,被標記刪除的數據,版本數溢出的數據)

2. Compaction引入的問題

Compaction會致使寫入放大

image

如上圖所示,第一個HFile通過屢次minor compaction和一次major compaction後,數據被讀取和寫入屢次。

在Facebook Messages系統中,業務讀寫比爲99:1,而最終反映到磁盤中,讀寫比卻變爲了36:64。WAL,HDFS Replication,Compaction以及Caching,共同致使了磁盤寫IO的顯著放大。

3. 如何合理的執行Compaction?

compaction能夠經過減小HFile的數據來下降讀取延時,可是compaction次數不能過多,以控制寫入放大的影響。

咱們須要在讀取延時(多compaction)和寫入放大(少compaction)中折衷,調研本身的業務模型,合理執行Compaction

  • 業務模型參考維度:
寫入數據類型/單條記錄大小(是不是KB甚至小於KB級別的小記錄?仍是MB甚至更大的圖片/小文件數據?)
業務讀寫比例
隨着時間的不斷推移,RowKey的數據分佈呈現什麼特色?
數據在讀寫上是否有冷熱特色?
是否只讀取/改寫最近產生的數據?
是否有頻繁的更新與刪除?
數據是否有TTL限制?
是否有較長時間段的業務高峯期和業務低谷期?

4. 幾種Compaction策略

  • Stripe Compaction

將一個Region劃分爲多個Stripes(能夠理解爲Sub-Regions),Compaction能夠控制在Stripe(Sub-Region)層面發生,而不是整個Region級別,這樣能夠有效下降Compaction對IO資源的佔用。

適合場景:rowkey是按Stripe順序寫入。

  • Date Tiered Compaction
    Date Tiered Compaction在選擇文件執行合併的時候,會感知Date信息,使得Compaction時,不須要將新老數據合併在一塊兒。

時序數據就是最典型的一個適用場景。

  • MOB Compaction
    如何存儲MB級別的Blob(如圖片之類的小文件)數據?

將Blob數據與描述Blob的元數據分離存儲,Blob元數據採用正常的HBase的數據存儲方式,而Blob數據存儲在額外的MOB文件中,但在Blob元數據行中,存儲了這個MOB文件的路徑信息。MOB文件本質仍是一個HFile文件,但這種HFile文件不參與HBase正常的Compaction流程。僅僅合併Blob元數據信息,寫IO放大的問題就獲得了有效的緩解。

  • Default Compaction

在選擇待合併的文件時是在整個Region級別進行選擇的

若是上述幾種Compaction策略都沒法很好的知足業務需求的話,用戶還能夠自定義Compaction策略,由於HBase已經具有良好的Compaction插件化機制。

5. 如何選擇待合併的文件(minor compaction)

若是一次選擇了過多的文件: 對於讀取時延的影響時間範圍可能比較長,但Compaction產生的寫IO總量較低。

若是一次選擇了較少的文件: 可能致使過於頻繁的合併,致使寫IO被嚴重放大。

  • RatioBasedCompactionPolicy
    f[start].size <= ratio * (f[start+1].size + ….. + f[end – 1].size)

image

  • ExploringCompactionPolicy

RatioBasedCompactionPolicy雖然選擇出來了一種文件組合,但其實這個文件組合並非最優的,所以它指望在全部的候選組合中,選擇一組性價比更高的組合,性價比更高的定義爲:文件數相對較多,而總體大小卻較小。這樣,便可以有效下降HFiles數量,又可能有效控制Compaction所佔用的IO總量。
RatioBasedCompactionPolicy僅僅是在自定義的規則之下找到第一個」可行解「便可,而ExploringCompactionPolicy卻在儘量的去尋求一種自定義評價標準中的」最優解「。

請必定要結合實際的業務場景,選擇合理的Compaction策略,經過不斷的測試和觀察,選擇合理的配置,何謂合理?能夠觀察以下幾點:
1. 寫入吞吐量可否知足要求。隨着時間的推移,寫入吞吐量是否會不斷下降?
2. 讀取時延可否知足要求。隨着時間的推移,讀取時延是否出現明顯的增大?
3. 觀察過程當中,建議不斷的統計分析Compaction產生的IO總量,以及隨着時間的變化趨勢。

參考文獻

一條數據的HBase之旅,簡明HBase入門教程-Flush與Compaction

相關文章
相關標籤/搜索