一條數(shù)據(jù)的HBase之旅,簡明HBase入門教程-Flush與Compaction

Flush與Compaction其實屬于Write流程的繼續(xù),所以本文應(yīng)該稱之為"Write后傳"汹桦。在2.0版本中,最主要的變化就是新增了In-memory Flush/Compaction鉴裹,而DateTieredCompaction并不算2.0新加入的特性舞骆,2.0版本在Compaction核心算法方面并沒有什么新的突破。本文將帶你探討Compaction的一些本質(zhì)問題径荔。

在閱讀本文之前督禽,希望你已經(jīng)閱讀過:

一條數(shù)據(jù)的HBase之旅,簡明HBase入門教程-開篇

一條數(shù)據(jù)的HBase之旅猖凛,簡明HBase入門教程-Write全流程

前文回顧

前文《一條數(shù)據(jù)的HBase之旅,簡明HBase入門教程:Write全流程》主要講了如下內(nèi)容:

1. 介紹HBase寫數(shù)據(jù)可選接口以及接口定義
2. 通過一個樣例绪穆,介紹了RowKey定義以及列定義的一些方法辨泳,以及如何組裝Put對象
3. 數(shù)據(jù)路由虱岂,數(shù)據(jù)分發(fā)、打包菠红,以及Client通過RPC發(fā)送寫數(shù)據(jù)請求至RegionServer
4. RegionServer接收數(shù)據(jù)以后第岖,將數(shù)據(jù)寫到每一個Region中。寫數(shù)據(jù)流程先寫WAL再寫MemStore试溯,這里展開了一些技術(shù)細(xì)節(jié)
5. 簡單介紹了HBase權(quán)限控制模型

至此蔑滓,數(shù)據(jù)已經(jīng)被寫入WAL與MemStore,可以說數(shù)據(jù)已經(jīng)被成功寫到HBase中了遇绞。事實上键袱,上篇文章講到的Flush流程是"簡化"后的流程,在2.0版本中摹闽,這里已經(jīng)變的更加復(fù)雜蹄咖。

本文思路

  1. 回顧Flush&Compaction舊流程
  2. 介紹2.0版本的In-memory Flush & Compaction特性
  3. 介紹Compaction要解決的本質(zhì)問題是什么
  4. 在選擇合理的Compaction策略之前,用戶應(yīng)該從哪些維度調(diào)研自己的業(yè)務(wù)模型
  5. HBase現(xiàn)有的Compaction策略有哪些付鹿,各自的適用場景是什么
  6. Compaction如何選擇待合并的文件
  7. 關(guān)于Compaction更多的一些思考
  8. 本計劃列出所有的價值問題單澜汤,但篇幅文字受限《尕遥可以點擊"閱讀原文"鏈接參考文末References信息部分

Flush&Compaction

這是1.X系列版本以及更早版本中的Flush&Compaction行為:

MemStore中的數(shù)據(jù)俊抵,達到一定的閾值,被Flush成HDFS中的HFile文件坐梯。

但隨著Flush次數(shù)的不斷增多徽诲,HFile的文件數(shù)量也會不斷增多,那這會帶來什么影響烛缔?在HBaseCon 2013大會上馏段,Hontonworks的名為《Compaction Improvements in Apache HBase》的演講主題中,提到了他們測試過的隨著HFile的數(shù)量的不斷增多對讀取時延帶來的影響:

盡管關(guān)于Read的流程在后面文章中才會講到践瓷,但下圖可以幫助我們簡單的理解這其中的原因:


圖中說明了從一個文件中指定RowKey為“66660000431^201803011300”的記錄院喜,以及從兩個文件中讀取該行記錄的區(qū)別,明顯晕翠,從兩個文件中讀取喷舀,將導(dǎo)致更多的IOPS。這就是HBase Compaction存在的一大初衷淋肾,Compaction可以將一些HFile文件合并成較大的HFile文件硫麻,也可以把所有的HFile文件合并成一個大的HFile文件,這個過程可以理解為:將多個HFile的“交錯無序狀態(tài)”樊卓,變成單個HFile的“有序狀態(tài)”拿愧,降低讀取時延。小范圍的HFile文件合并碌尔,稱之為Minor Compaction浇辜,一個列族中將所有的HFile文件合并券敌,稱之為Major Compaction。除了文件合并范圍的不同之外柳洋,Major Compaction還會清理一些TTL過期/版本過舊以及被標(biāo)記刪除的數(shù)據(jù)待诅。下圖直觀描述了舊版本中的Flush與Compaction流程:

Flush

在2.0版本中,F(xiàn)lush的行為發(fā)生了變化熊镣,默認(rèn)的Flush卑雁,僅僅是將正在寫的MemStore中的數(shù)據(jù)歸檔成一個不可變的Segment,而這個Segment依然處于內(nèi)存中绪囱,這就是2.0的新特性:In-memory Flush and Compaction测蹲,而且該特性在2.0版本中已被默認(rèn)啟用(系統(tǒng)表除外)。
上文中簡單提到了MemStore的核心是一個CellSet毕箍,但到了這里弛房,我們可以發(fā)現(xiàn),MemStore的結(jié)構(gòu)其實更加復(fù)雜:MemStore由一個可寫的Segment而柑,以及一個或多個不可寫的Segments構(gòu)成文捶。


MemStore中的數(shù)據(jù)先Flush成一個Immutable的Segment,多個Immutable Segments可以在內(nèi)存中進行Compaction媒咳,當(dāng)達到一定閾值以后才將內(nèi)存中的數(shù)據(jù)持久化成HDFS中的HFile文件粹排。

看到這里,可能會有這樣的疑問:這樣做的好處是什么涩澡?為何不直接調(diào)大MemStore的Flush Size顽耳?

如果MemStore中的數(shù)據(jù)被直接Flush成HFile,而多個HFile又被Compaction合并成了一個大HFile妙同,隨著一次次Compaction發(fā)生以后射富,一條數(shù)據(jù)往往被重寫了多次,這帶來顯著的IO放大問題粥帚,另外胰耗,頻繁的Compaction對IO資源的搶占,其實也是導(dǎo)致HBase查詢時延大毛刺的罪魁禍?zhǔn)字?/strong>芒涡。而In-memory Flush and Compaction特性可以有力改善這一問題柴灯。

那為何不干脆調(diào)大MemStore的大小费尽?這里的本質(zhì)原因在于赠群,ConcurrentSkipListMap在存儲的數(shù)據(jù)量達到一定大小以后,寫入性能將會出現(xiàn)顯著的惡化旱幼。

在融入了In-Memory Flush and Compaction特性之后查描,F(xiàn)lush與Compaction的整體流程演變?yōu)椋?div id="suekw37" class="image-package">

關(guān)于Flush執(zhí)行的策略

一個Region中是否執(zhí)行Flush,原來的默認(rèn)行為是通過計算Region中所有Column Family的整體大小,如果超過了一個閾值冬三,則這個Region中所有的Column Family都會被執(zhí)行Flush鸯两。

2.0版本中合入了0.89-fb版本中的一個特性:HBASE-10201/HBASE-3149:Make flush decisions per column family。

2.0版本中默認(rèn)啟用的Flush策略為FlushAllLargeStoresPolicy长豁,也就是說,這個策略使得每一次只Flush超出閾值大小的Column Family忙灼,如果都未超出大小匠襟,則所有的Column Family都會被Flush。

改動之前该园,一個Region中所有的Column Family的Flush都是同步的酸舍,雖然容易導(dǎo)致大量的小HFile,但也有好處里初,尤其是對于WAL文件的快速老化啃勉,避免導(dǎo)致過多的WAL文件。而如果這些Column Family的Flush不同步以后双妨,可能會導(dǎo)致過多的WAL文件(過多的WAL文件會觸發(fā)一些擁有老數(shù)據(jù)的Column Family執(zhí)行Flush)淮阐,這里需要結(jié)合業(yè)務(wù)場景實測一下。如果每一行數(shù)據(jù)的寫入刁品,多個Column Family的數(shù)據(jù)都是同步寫入的泣特,那么,這個默認(rèn)策略可能并不合適挑随。

Compaction

在這個章節(jié)状您,我們繼續(xù)探討HBase Compaction,主要是想理清這其中所涉及的一些"道"與"術(shù)":

  • "道":HBase Compaction要解決的本質(zhì)問題是什么兜挨?
  • "術(shù)":針對HBase Compaction的問題本質(zhì)膏孟,HBase有哪些具體的改進/優(yōu)秀實踐?

Compaction會導(dǎo)致寫入放大
我們先來看看Facebook在Fast 14提交的論文《Analysis of HDFS Under HBase: A Facebook Messages Case Study》所提供的一些測試結(jié)論(在我之前寫的一篇文章《從HBase中移除WAL拌汇?3D XPoint技術(shù)帶來的變革》已經(jīng)提到過):

在Facebook Messages業(yè)務(wù)系統(tǒng)中柒桑,業(yè)務(wù)讀寫比為99:1,而最終反映到磁盤中担猛,讀寫比卻變?yōu)榱?6:64幕垦。>WAL,HDFS Replication傅联,Compaction以及Caching先改,共同導(dǎo)致了磁盤寫IO的顯著放大。
雖然距離論文發(fā)表已經(jīng)過去幾年蒸走,但問題本質(zhì)并未發(fā)生明顯變化仇奶。尤其是在一個寫多讀少的應(yīng)用中,因Compaction帶來的寫放大(Write Amplification)尤其明顯,下圖有助于你理解寫放大的原因:

隨著不斷的執(zhí)行Minor Compaction以及Major Compaction该溯,可以看到岛抄,這條數(shù)據(jù)被反復(fù)讀取/寫入了多次,這是導(dǎo)致寫放大的一個關(guān)鍵原因狈茉,這里的寫放大夫椭,涉及到網(wǎng)絡(luò)IO與磁盤IO,因為數(shù)據(jù)在HDFS中默認(rèn)有三個副本氯庆。

Compaction的本質(zhì)

我們先來思考一下蹭秋,在集群中執(zhí)行Compaction,本質(zhì)是為了什么堤撵?容易想到如下兩點原因:

  • 減少HFile文件數(shù)量仁讨,減少文件句柄數(shù)量,降低讀取時延

  • Major Compaction可以幫助清理集群中不再需要的數(shù)據(jù)(過期數(shù)據(jù)实昨,被標(biāo)記刪除的數(shù)據(jù)洞豁,版本數(shù)溢出的數(shù)據(jù))

很多HBase用戶在集群中關(guān)閉了自動Major Compaction,為了降低Compaction對IO資源的搶占荒给,但出于清
理數(shù)據(jù)的需要丈挟,又不得不在一些非繁忙時段手動觸發(fā)Major Compaction,這樣既可以有效降低存儲空間志电,也>可以有效降低讀取時延礁哄。

而關(guān)于如何合理的執(zhí)行Compaction,我們需要結(jié)合業(yè)務(wù)數(shù)據(jù)特點溪北,不斷的權(quán)衡如下兩點:

  • 避免因文件數(shù)不斷增多導(dǎo)致讀取時延出現(xiàn)明顯增大
  • 合理控制寫入放大

HFile文件數(shù)量一定會加大讀取時延嗎桐绒?也不一定,因為這里與RowKey的分布特點有關(guān)之拨。我們通過列舉幾個典型場景來說明一下不同的RowKey分布茉继,為了方便理解,我們先將一個Region的RowKey Range進一步劃分成多個Sub-Range蚀乔,來說明不同的RowKey分布是如何填充這些Sub-Ranges的:

下面的不同行代表不同的時間點(我們使用不斷遞增的時間點T1,T2,T3,T4烁竭,來描述隨著時間演變而產(chǎn)生的RowKey分布變化):
分布A

在這個Region中,某一個時間段只填充與之有關(guān)的一個Sub-Range吉挣,RowKey隨著時間的演進派撕,整體呈現(xiàn)遞增趨勢。但在填充每一個Sub-Range的時候睬魂,又可能有如下兩種情形(以Sub-Range1的填充為例终吼,為了區(qū)別于T1T4,我們使用了另外4個時間點TaTd):

分布A-a

這種情形下氯哮,RowKey是嚴(yán)格遞增的际跪。
分布A-b

這種情形下,RowKey在Sub-Range1的范圍內(nèi)是完全隨機的。

下面則是一種隨機RowKey的場景姆打,也就是說良姆,每一個時間點產(chǎn)生的數(shù)據(jù)都是隨機分布在所有的Sub-Range中的:
分布B

對于分布A-a來說,不同的HFile文件在RowKey Range(該HFile文件所涉及到的最小數(shù)據(jù)RowKey與最大數(shù)據(jù)RowKey構(gòu)成的RowKey區(qū)間)上并不會產(chǎn)生重疊幔戏,如果要基于RowKey讀取一行數(shù)據(jù)玛追,只需要查看一個文件即可,而不需要查看所有的文件闲延,這里完全可以通過優(yōu)化讀取邏輯來實現(xiàn)豹缀。即使不做Compaction,對于讀取時延的影響并不明顯(當(dāng)然慨代,從降低文件句柄數(shù)量,降低HDFS側(cè)的小文件數(shù)量的維度來考慮啸如,Compaction還是有意義的)侍匙。

對于分布B來說,如果有多個HFiles文件叮雳,如果想基于RowKey讀取一行數(shù)據(jù)想暗,則需要查看多個文件,因為不同的HFile文件的RowKey Range可能是重疊的帘不,此時说莫,Compaction對于降低讀取時延是非常必要的。

調(diào)研自己的業(yè)務(wù)模型

在選擇一個合理的Compaction策略之前寞焙,應(yīng)該首先調(diào)研自己的業(yè)務(wù)模型储狭,下面是一些參考維度:

1.寫入數(shù)據(jù)類型/單條記錄大小 ;是否是KB甚至小于KB級別的小記錄?還是MB甚至更大的圖片/小文件數(shù)據(jù)捣郊?

2.業(yè)務(wù)讀寫比例

3.隨著時間的不斷推移辽狈,RowKey的數(shù)據(jù)分布呈現(xiàn)什么特點?

4.數(shù)據(jù)在讀寫上是否有冷熱特點? 是否只讀取/改寫最近產(chǎn)生的數(shù)據(jù)呛牲?

5.是否有頻繁的更新與刪除?

6.數(shù)據(jù)是否有TTL限制?

7.是否有較長時間段的業(yè)務(wù)高峰期和業(yè)務(wù)低谷期刮萌?

幾種Compaction策略
HBase中有幾種典型的Compaction策略,來應(yīng)對幾類典型的業(yè)務(wù)場景:

一. Stripe Compaction

它的設(shè)計初衷是娘扩,Major Compaction占用大量的IO資源着茸,所以很多HBase用戶關(guān)閉了自動觸發(fā)的Major Compaction,改為手動觸發(fā)琐旁,因為Major Compaction依然會被用來清理一些不再需要的數(shù)據(jù)涮阔。

隨著時間的推移,Major Compaction要合并的文件總Size越來越大灰殴,但事實上澎语,真的有必要每一次都將所有的文件合并成一個大的HFile文件嗎?尤其是,不斷的將一些較老的數(shù)據(jù)和最新的數(shù)據(jù)合并在一起擅羞,對于一些業(yè)務(wù)場景而言根本就是不必要的尸变。

因此,它的設(shè)計思路為:

將一個Region劃分為多個Stripes(可以理解為Sub-Regions)减俏,Compaction可以控制在Stripe(Sub-Region)層面發(fā)生召烂,而不是整個Region級別,這樣可以有效降低Compaction對IO資源的占用娃承。

那為何不直接通過設(shè)置更多的Region數(shù)量來解決這個問題奏夫?更多的Region意味著會加大HBase集群的負(fù)擔(dān),尤其是加重Region Assignment流程的負(fù)擔(dān)历筝,另外酗昼,Region增多,MemStore占用的總體內(nèi)存變大梳猪,而在實際內(nèi)存無法變大的情況下麻削,只會使得Flush更早被觸發(fā),F(xiàn)lush的質(zhì)量變差春弥。

新Flush產(chǎn)生的HFile文件呛哟,先放到一個稱之為L0的區(qū)域,L0中Key Range是Region的完整Key Range匿沛,當(dāng)對L0中的文件執(zhí)行Compaction時扫责,再將Compaction的結(jié)果輸出到對應(yīng)的Stripe中:

HBase Document中這么描述Stripe Compaction的適用場景:

  • Large regions. You can get the positive effects of smaller regions without additional overhead for MemStore and region management overhead.

  • Non-uniform keys, such as time dimension in a key. Only the stripes receiving the new keys will need to compact. Old data will not compact as often, if at all

在我們上面列舉的幾種RowKey分布的場景中,分布A(含分布A-a逃呼,分布A-b)就是特別適合Stripe Compaction的場景鳖孤,因為僅僅新寫入數(shù)據(jù)的Sub-Range合并即可,而對于老的Sub-Range中所關(guān)聯(lián)的數(shù)據(jù)文件抡笼,根本沒有必要再執(zhí)行Compaction淌铐。

Stripe Compaction關(guān)于Sub-Region的劃分,其實可以加速Region Split操作蔫缸,因為有的情形下腿准,直接將所有的Stripes分成兩部分即可。

二. Date Tiered Compaction

我們假設(shè)有這樣一種場景:

  • 新數(shù)據(jù)的產(chǎn)生與時間有關(guān)拾碌,而且無更新吐葱、刪除場景

  • 讀取時通常會指定時間范圍,而且通常讀取最近的數(shù)據(jù)

在這種情形下校翔,如果將老數(shù)據(jù)與新數(shù)據(jù)合并在一起弟跑,那么,指定時間范圍讀取時防症,就需要掃描一些不必要的老數(shù)據(jù):因為合并后孟辑,數(shù)據(jù)按RowKey排序哎甲,RowKey排序未必與按照數(shù)據(jù)產(chǎn)生的時間排序一致,這使得新老數(shù)據(jù)交叉存放饲嗽,而掃描時老數(shù)據(jù)也會被讀到炭玫。

這是Date Tiered Compaction的設(shè)計初衷,Date Tiered Compaction在選擇文件執(zhí)行合并的時候貌虾,會感知Date信息吞加,使得Compaction時,不需要將新老數(shù)據(jù)合并在一起尽狠。這對于基于Time Range的Scan操作是非常有利的衔憨,因為與本次Scan不相關(guān)的文件可以直接忽略

什么是Time Range Based Scan?

HBase的Scan查詢袄膏,通常都是指定RowKey的Range的践图,但HBase也支持這樣一類查詢:通過指定一個起始的Timestamp,掃描出所有的落在此Timestamp Range中的所有數(shù)據(jù)沉馆,這就是Time Range Based Scan码党。

可以參考接口:Scan#setTimeRange(long minStamp, long maxStamp)

Time Range Based Scan可以用來實現(xiàn)針對HBase數(shù)據(jù)表的增量數(shù)據(jù)導(dǎo)出/備份能力。

容易想到悍及,時序數(shù)據(jù)就是最典型的一個適用場景。但需要注意的是接癌,如下場景并不適合使用Date Tiered Compaction:

  • 讀取時通常不指定時間范圍
  • 涉及頻繁的更新與刪除
  • 寫入時主動指定時間戳心赶,而且可能會指定一個未來的時間戳
  • 基于bulk load加載數(shù)據(jù),而且加載的數(shù)據(jù)可能會在時間范圍上重疊
三. MOB Compaction

能否使用HBase來存儲MB級別的Blob(如圖片之類的小文件)數(shù)據(jù)缺猛?

這是很多應(yīng)用面臨的一個基礎(chǔ)問題缨叫,因為這些數(shù)據(jù)相比于普通的存儲于HBase中的結(jié)構(gòu)化/半結(jié)構(gòu)化數(shù)據(jù)顯得過大了,而如果將這些數(shù)據(jù)直接存儲成HDFS中的獨立文件荔燎,會加重HDFS的NameNode的負(fù)擔(dān)耻姥,再者,如何索引這些小文件也是一個極大的痛點有咨。

當(dāng)然琐簇,也有人采用了這樣的方式:將多個小文件合并成HDFS上的一個大文件,這樣子可以減輕HDFS的NameNode的負(fù)擔(dān)座享,但需要維護每一個小文件的索引信息(文件名以及每一個小文件的偏移信息)婉商。

如果存這些這些小文件時,像普通的結(jié)構(gòu)化數(shù)據(jù)/半結(jié)構(gòu)化數(shù)據(jù)一樣渣叛,直接寫到HBase中丈秩,會有什么問題?這樣子多條數(shù)據(jù)可以被合并在較大的HFile文件中淳衙,減輕了NameNode的負(fù)擔(dān)蘑秽,同時解決了快速索引的問題饺著。但基于前面的內(nèi)容,我們已經(jīng)清楚知道了Compaction帶來的寫放大問題肠牲。試想一下幼衰,數(shù)MB級別的Blob數(shù)據(jù),被反復(fù)多次合并以后埂材,會帶來什么樣的影響塑顺?這對IO資源的搶占將會更加嚴(yán)重。

因此俏险,HBase的MOB特性的設(shè)計思想為:將Blob數(shù)據(jù)與描述Blob的元數(shù)據(jù)分離存儲严拒,Blob元數(shù)據(jù)采用正常的HBase的數(shù)據(jù)存儲方式,而Blob數(shù)據(jù)存儲在額外的MOB文件中竖独,但在Blob元數(shù)據(jù)行中裤唠,存儲了這個MOB文件的路徑信息。MOB文件本質(zhì)還是一個HFile文件莹痢,但這種HFile文件不參與HBase正常的Compaction流程种蘸。僅僅合并Blob元數(shù)據(jù)信息,寫IO放大的問題就得到了有效的緩解竞膳。

MOB Compaction也主要是針對MOB特性而存在的航瞭,這里涉及到數(shù)據(jù)在MOB文件與普通的HFile文件之間的一些流動,尤其是MOB的閾值大小發(fā)生變更的時候(即當(dāng)一個列超過預(yù)設(shè)的配置值時坦辟,才被認(rèn)定為MOB)刊侯,本文暫不展開過多的細(xì)節(jié)。

在HBase社區(qū)中锉走,MOB特性(HBASE-11339)一直在一個獨立的特性分支中開發(fā)的滨彻,直到2.0版本才最終合入進來(華為的FusionInsight的HBase版本中,以及華為云的CloudTable的HBase版本中挪蹭,都包含了完整的MOB特性)亭饵。

關(guān)于mob可查看另一篇文章HBase 的MOB壓縮分區(qū)策略介紹

四. Default Compaction

就是默認(rèn)的Compaction行為,2.0版本和舊版本中的行為沒有什么明顯變化梁厉。

所謂的Default Compaction辜羊,具有更廣泛的適用場景,它在選擇待合并的文件時是在整個Region級別進行選擇的词顾,所以往往意味著更高的寫IO放大只冻。

在實際應(yīng)用中,應(yīng)該結(jié)合自己的應(yīng)用場景選擇合適的Compaction策略计技,如果前幾種策略能夠匹配自己的應(yīng)用場景喜德,那么應(yīng)該是優(yōu)選的(這幾個策略的質(zhì)量狀態(tài)如何尚不好判斷,建議結(jié)合業(yè)務(wù)場景進行實測觀察)垮媒,否則應(yīng)該選擇Default Compaction舍悯。

如果上述幾種Compaction策略都無法很好的滿足業(yè)務(wù)需求的話航棱,用戶還可以自定義Compaction策略因為HBase已經(jīng)具備良好的Compaction插件化機制萌衬。

如何選擇待合并的文件
無論哪種Compaction策略饮醇,都涉及一個至關(guān)重要的問題:“如何選擇待合并的文件列表”
Major Compaction是為了合并所有的文件,所以秕豫,不存在如何選擇文件的問題朴艰。
選擇文件時,應(yīng)該考慮如下幾個原則:

  1. 選擇合理的文件數(shù)量
    如果一次選擇了過多的文件: 對于讀取時延的影響時間范圍可能比較長混移,但Compaction產(chǎn)生的寫IO總量較低祠墅。
    如果一次選擇了較少的文件: 可能導(dǎo)致過于頻繁的合并,導(dǎo)致寫IO被嚴(yán)重放大歌径。

  2. 選擇的文件在時間產(chǎn)生順序上應(yīng)該是連續(xù)的毁嗦,即應(yīng)該遵循HBase的Sequence ID的順序

這樣子,HBase的讀取時可以做一些針對性的優(yōu)化回铛,例如狗准,如果在最新的文件中已經(jīng)讀到了一個RowKey的記錄,那就沒有必要再去看較老的文件茵肃。

在HBase中腔长,有一種"歷史悠久"的選擇文件的策略,名為ExploringCompactionPolicy验残,即使在最新的版本中捞附,該策略依然在協(xié)助發(fā)揮作用,它選擇文件的原理如下(下面的圖片和例子源自HBASE-6371):

將HFile文件從老到新的順序排序胚膊,通常故俐,舊文件較大想鹰,因為舊文件更可能是被合并過的文件紊婉。
每一次需要從文件隊列中選取一個合適的開始文件位置,通過如下算法:

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

找到一個滿足條件的開始位置辑舷,以及滿足條件的文件組合喻犁。

舉例:假設(shè)ratio = 1.0:

  1. 如果候選文件[1200, 500, 150, 80, 50, 25, 12, 10],則最終選擇出來的需要合并的文件列表為[150, 80, 50, 25, 12, 10]


    image
  2. 如果候選文件[1200, 500, 150, 80, 25, 10]何缓,則選不出任何文件肢础。
    每一次Minor Compaction所涉及的文件數(shù)目都有上下限。如果超過了碌廓,會減去一些文件传轰,如果小于下限,則忽略此次Compaction操作谷婆。待選擇的文件也有大小限制慨蛙,如果超出了預(yù)設(shè)大小辽聊,就不會參與Compaction。這里可以理解為:Minor Compaction的初衷只是為了合并較小的文件期贫。另外跟匆,BulkLoad產(chǎn)生的文件,在Minor Compaction階段會被忽略通砍。
    RatioBasedCompactionPolicy曾一度作為主力文件選擇算法沿用了較長的時間玛臂,后來,出現(xiàn)了一種ExploringCompactionPolicy封孙,它的設(shè)計初衷為:

RatioBasedCompactionPolicy雖然選擇出來了一種文件組合迹冤,但其實這個文件組合并不是最優(yōu)的,因此它期望在所有的候選組合中敛瓷,選擇一組性價比更高的組合叁巨,性價比更高的定義為:文件數(shù)相對較多,而整體大小卻較小呐籽。這樣锋勺,即可以有效降低HFiles數(shù)量,又可能有效控制Compaction所占用的IO總量狡蝶。

也可以這么理解它們之間的一些不同:

RatioBasedCompactionPolicy僅僅是在自定義的規(guī)則之下找到第一個"可行解"即可庶橱,而ExploringCompactionPolicy卻在盡可能的去尋求一種自定義評價標(biāo)準(zhǔn)中的"最優(yōu)解"。

另外贪惹,需要說明的一點:ExploringCompactionPolicy在選擇候選組合時苏章,正是采用了RatioBasedCompactionPolicy中的文件選擇算法。

更多的一些思考
Compaction會導(dǎo)致寫入放大奏瞬,前面的內(nèi)容中已經(jīng)反復(fù)提及了很多次皇筛。在實際應(yīng)用中,你是否關(guān)注過Compaction對于查詢毛刺的影響(查詢時延總是會出現(xiàn)偶發(fā)性的陡增)蒲赂?

關(guān)于Compaction的參數(shù)調(diào)優(yōu)给梅,我們可能看到過這樣的一些建議:盡可能的減少每一次Compaction的文件數(shù)量,目的是為了減短每一次Compaction的執(zhí)行時間珍昨。這就好比县耽,采用Java GC算法中的CMS算法時,每一次回收少量的無引用對象镣典,盡管GC被觸發(fā)的頻次會增大兔毙,但可以有效降低Full GC的發(fā)生次數(shù)和發(fā)生時間。

但在實踐中兄春,這可能并不是一個合理的建議澎剥,例如,HBase默認(rèn)的觸發(fā)Minor Compaction的最小文件數(shù)量為3赶舆,但事實上哑姚,對于大多數(shù)場景而言趾唱,這可能是一個非常不合理的默認(rèn)值,在我們的測試中蜻懦,將最小文件數(shù)加大到10個甜癞,我們發(fā)現(xiàn)對于整體的吞吐量以及查詢毛刺,都有極大的改進宛乃,所以悠咱,這里的建議為:Minor Compaction的文件數(shù)量應(yīng)該要結(jié)合實際業(yè)務(wù)場景設(shè)置合理的值。另外征炼,在實踐中析既,合理的限制Compaction資源的占用也是非常關(guān)鍵的,如Compaction的并發(fā)執(zhí)行度谆奥,以及Compaction的吞吐量以及網(wǎng)絡(luò)帶寬占用等等眼坏。

另外,需要關(guān)注到的一點:Compaction會影響B(tài)lock Cache酸些,因為HFile文件發(fā)生合并以后宰译,舊HFile文件所關(guān)聯(lián)的被Cache的Block將會失效。這也會影響到讀取時延魄懂。HBase社區(qū)有一個問題單(HBASE-20045)沿侈,試圖在Compaction時緩存一些最近的Blocks。

在Facebook的那篇論文中市栗,還有一個比較有意思的實踐:


他們將Compaction下推到存儲層(HDFS)執(zhí)行缀拭,這樣,每一個DateNode在本地合并自己的文件填帽,這樣可以降低一半以上的網(wǎng)絡(luò)IO請求蛛淋,但本地磁盤IO請求會增大,這事實上是用磁盤IO資源來換取昂貴的網(wǎng)絡(luò)IO資源篡腌。在我們自己的測試中也發(fā)現(xiàn)褐荷,將Compaction下推到HDFS側(cè)執(zhí)行,能夠明顯的優(yōu)化讀寫時延毛刺問題哀蘑。

總結(jié)

本文基于2.0版本闡述了Flush與Compaction流程诚卸,講述了Compaction所面臨的本質(zhì)問題葵第,介紹了HBase現(xiàn)有的幾種Compaction策略以及各自的適用場景绘迁,更多是從原理層面展開的,并沒有過多講述如何調(diào)整參數(shù)的實際建議卒密,唯一的建議為:請一定要結(jié)合實際的業(yè)務(wù)場景缀台,選擇合理的Compaction策略,通過不斷的測試和觀察哮奇,選擇合理的配置膛腐,何謂合理睛约?可以觀察如下幾點:

  • 寫入吞吐量能否滿足要求。隨著時間的推移哲身,寫入吞吐量是否會不斷降低辩涝?

  • 讀取時延能否滿足要求。隨著時間的推移勘天,讀取時延是否出現(xiàn)明顯的增大怔揩?

  • 觀察過程中,建議不斷的統(tǒng)計分析Compaction產(chǎn)生的IO總量脯丝,以及隨著時間的變化趨勢商膊。2.0版本中盡管增加了一些與Compaction相關(guān)的Metrics信息,但關(guān)于Compaction IO總量的統(tǒng)計依然是非常不充分的宠进,這一點可以自己定制實現(xiàn)晕拆,如果你有興趣,也完全可以貢獻給社區(qū)材蹬。

原文出自:一條數(shù)據(jù)的HBase之旅实幕,簡明HBase入門教程-Flush與Compaction

更多技術(shù)交流,可關(guān)注微信交流群堤器,微信公眾號等:

或參考文章: HBase中文社區(qū)官網(wǎng)茬缩、交流群

1. 微信群

掃描添加小編微信好友(或搜索微信號: Mr_wanyue 添加),回復(fù): HBase 加群

2. 釘釘群:

掃一掃添加

3. 微信公眾號:
掃描關(guān)注

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吼旧,一起剝皮案震驚了整個濱河市凰锡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌圈暗,老刑警劉巖掂为,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異员串,居然都是意外死亡勇哗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門寸齐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欲诺,“玉大人,你說我怎么就攤上這事渺鹦∪欧ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵毅厚,是天一觀的道長塞颁。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么祠锣? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任酷窥,我火速辦了婚禮,結(jié)果婚禮上伴网,老公的妹妹穿的比我還像新娘蓬推。我一直安慰自己,他們只是感情好澡腾,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布拳氢。 她就那樣靜靜地躺著,像睡著了一般蛋铆。 火紅的嫁衣襯著肌膚如雪馋评。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天刺啦,我揣著相機與錄音留特,去河邊找鬼。 笑死玛瘸,一個胖子當(dāng)著我的面吹牛蜕青,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播糊渊,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼右核,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渺绒?” 一聲冷哼從身側(cè)響起贺喝,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宗兼,沒想到半個月后躏鱼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡殷绍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年染苛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片主到。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡茶行,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出登钥,到底是詐尸還是另有隱情畔师,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布怔鳖,位于F島的核電站茉唉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏结执。R本人自食惡果不足惜度陆,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望献幔。 院中可真熱鬧懂傀,春花似錦、人聲如沸蜡感。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郑兴。三九已至犀斋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間情连,已是汗流浹背叽粹。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留却舀,地道東北人虫几。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像挽拔,于是被迫代替她去往敵國和親辆脸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容