HBase系列 - 內(nèi)部機制 MemstoreFlush、StoreFile Compaction、Region Split詳解

前言

HBase以高并發(fā)、搞可靠、高性能而聞名,而Compact和Split功能貫穿了hbase的整個寫入過程,而熟悉Compact和Split內(nèi)部邏輯以及控制參數(shù)才能根據(jù)具體的實際業(yè)務(wù)場景來調(diào)整參數(shù)滿足業(yè)務(wù)需要,對HBase優(yōu)化以及問題排查是至關(guān)重要的。

本文對 MemStore 的 Flush 進行說明,包括哪幾種條件會觸發(fā) Memstore Flush 及目前常見的刷寫策略(FlushPolicy)以及 Memstore Flush 后可能引起HBase的StoreFile Compaction 和 Region Split。

當(dāng)使用HBase到了瓶頸(內(nèi)存、cpu、IO)的時候,熟悉其內(nèi)部機制可以更好的針對場景去做trade-off。大多數(shù)情況下,都是磁盤IO存在問題。熟悉Memstore Flush、StoreFile Compaction、Region split 的話可以更加靈活的使用內(nèi)存和cpu去換去緊張的IO資源以及如何去避免被阻塞導(dǎo)致性能問題。

HBase 數(shù)據(jù)寫入總流程.png

如上圖所示:

當(dāng)RegionServer接收寫入請求后整個存儲過程的三個階段

  1. 當(dāng)達到一定的條件后Memstore會Flush生成Hfile
  2. 隨著Memstore Flush的HFile文件越來越多,可能嚴(yán)重影響到HBase的讀取性能。Flush文件時滿足條件的話會觸發(fā)Compaction操作。
  3. 隨著數(shù)據(jù)的不斷寫入,Region越來越膨脹,如果RegionSplitPolicy滿足之后也會自動進行拆分和遷移,在RegionServer之間負(fù)載均衡。

1.MemStore Flush

HBase MemStore Flush.png

Memstore中的數(shù)據(jù)在一定條件下會進行刷寫操作,使數(shù)據(jù)持久化到相應(yīng)的存儲設(shè)備上。

1.1 MemStore刷寫條件

1.1.1 整個 RegionServer 的 MemStore 占用內(nèi)存總和大于相關(guān)閾值

在該種情況下,RegionServer中所有region的單個memstore內(nèi)存占用都沒達到刷盤條件,但整體的內(nèi)存消耗已經(jīng)到一個非常危險的范圍,如果持續(xù)下去,很有可能造成RS的OOM,這個時候,需要進行memstore的刷盤,從而釋放內(nèi)存。

hbase.regionserver.global.memstore.size.lower.limit(默認(rèn)值0.95)
hbase.regionserver.global.memstore.size(默認(rèn)值0.4)

注意:0.99.0 之前以上兩個參數(shù)分別對應(yīng)的是
hbase.regionserver.global.memstore.lowerLimit(默認(rèn)值0.95)
hbase.regionserver.global.memstore.upperLimit(默認(rèn)值0.4)

HBase 為 RegionServer 的 MemStore 分配了一定的寫緩存,大小等于 hbase_heapsize(RegionServer 占用的堆內(nèi)存大?。? hbase.regionserver.global.memstore.size,也就是說寫緩存大概占用 RegionServer 整個 JVM 內(nèi)存使用量的 40%。

如果整個 RegionServer 的 MemStore 占用內(nèi)存總和大于hbase.regionserver.global.memstore.size.lower.limit * hbase.regionserver.global.memstore.size * hbase_heapsize 的時候,將會觸發(fā) MemStore 的刷寫。

舉個例子,如果我們 HBase 堆內(nèi)存總共是 32G,按照默認(rèn)的比例,那么觸發(fā) RegionServer 級別的 Flush 是 RS 中所有的 MemStore 占用寫內(nèi)存為:32 * 0.4 * 0.95 = 12.16G。

RegionServer 級別的 Flush 策略是按照其所有memstore的大小順序(由大到小)依次進行刷寫。直到region server中所有memstore的總大小減小到(hbase.regionserver.global.memstore.size.lower.limit * hbase.regionserver.global.memstore.size * hbase_heapsize)以下才會停止。

注意:如果達到了 RegionServer 級別的 Flush,那么當(dāng)前 RegionServer 的所有寫操作將會被阻塞,而且這個阻塞可能會持續(xù)到分鐘級別。

1.1.2 Region 中一個 MemStore 占用的內(nèi)存超過相關(guān)閾值

當(dāng)Region中一個memstroe的大小達到了hbase.hregion.memstore.flush.size,其所在region的所有memstore都會刷寫。我們每次調(diào)用 put、delete 等操作都會檢查的這個條件的。

hbase.hregion.memstore.flush.size(默認(rèn)值128M)
hbase.hregion.memstore.block.multiplier(默認(rèn)值為4)

但是如果我們的數(shù)據(jù)增加得很快,達到了hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier 的大小,也就是1284=512MB的時候,那么除了觸發(fā) MemStore 刷寫之外,HBase 還會在刷寫的時候同時阻塞*所有寫入該 Store 的寫請求。這時候如果你往對應(yīng)的 Store 寫數(shù)據(jù),會出現(xiàn) RegionTooBusyException 異常。

1.1.3 WAL文件的數(shù)量超過相關(guān)閾值

當(dāng)WAL文件的數(shù)量超過hbase.regionserver.max.logs,region會按照時間順序依次進行刷寫,直到WAL文件數(shù)量減小到hbase.regionserver.max.log以下。這個閾值(maxLogs)的計算公式

this.blocksize = WALUtil.getWALBlockSize(this.conf, this.fs, this.walDir);
float multiplier = conf.getFloat("hbase.regionserver.logroll.multiplier", 0.5f);
this.logrollsize = (long)(this.blocksize * multiplier);
this.maxLogs = conf.getInt("hbase.regionserver.maxlogs",
      Math.max(32, calculateMaxLogFiles(conf, logrollsize)));
 
public static long getWALBlockSize(Configuration conf, FileSystem fs, Path dir)
      throws IOException {
    return conf.getLong("hbase.regionserver.hlog.blocksize",
        CommonFSUtils.getDefaultBlockSize(fs, dir) * 2);
}
 
private int calculateMaxLogFiles(Configuration conf, long logRollSize) {
    Pair<Long, MemoryType> globalMemstoreSize = MemorySizeUtil.getGlobalMemStoreSize(conf);
    return (int) ((globalMemstoreSize.getFirst() * 2) / logRollSize);
}

也就是說,如果設(shè)置了 hbase.regionserver.maxlogs,那就是這個參數(shù)的值;否則是 max(32, hbase_heapsize * hbase.regionserver.global.memstore.size * 2 / logRollSize)。如果某個 RegionServer 的 WAL 數(shù)量大于 maxLogs 就會觸發(fā) MemStore 的刷寫。

WAL 數(shù)量觸發(fā)的刷寫策略是,找到最舊的 un-archived WAL 文件,并找到這個 WAL 文件對應(yīng)的 Regions, 然后對這些 Regions 進行刷寫。

1.1.4 到達自動刷寫的時間

到達自動刷寫的時間,也會觸發(fā)memstore flush。自動刷新的時間間隔由該屬性進行配置hbase.regionserver.optionalcacheflushinterval(默認(rèn)1小時)。

hbase.regionserver.optionalcacheflushinterval 默認(rèn)3600000

如果設(shè)定為0,則意味著關(guān)閉定時自動刷寫。

為了防止一次性有過多的 MemStore 刷寫,定期自動刷寫會有 0 ~ 5 分鐘的延遲,具體參見 PeriodicMemStoreFlusher 類的實現(xiàn)。

1.1.5 數(shù)據(jù)更新超過一定閾值

內(nèi)存中的更新數(shù)量已經(jīng)足夠多,比如超過 hbase.regionserver.flush.per.changes 參數(shù)配置,默認(rèn)為30000000,那么也是會觸發(fā)刷寫的。

1.1.6 手動觸發(fā)刷寫

? 手動觸發(fā)刷寫的兩個方式

  1. 調(diào)用 Admin 接口提供 的API 來觸發(fā) MemStore 的刷寫操作

    void flush(TableName tableName) throws IOException;
    void flushRegion(byte[] regionName) throws IOException;
    void flushRegionServer(ServerName serverName) throws IOException;
    
  2. hbase shell

    hbase> flush 'TABLENAME'
    hbase> flush 'REGIONNAME'
    hbase> flush 'ENCODED_REGIONNAME'
    hbase> flush 'REGION_SERVER_NAME'
    

1.2. 什么操作會觸發(fā)刷寫條件判斷

常見的 put、delete、append、increment、調(diào)用 flush 命令、Region 分裂、Region Merge、bulkLoad HFiles 以及給表做快照操作都會對上面的相關(guān)條件做檢查,以便判斷要不要做刷寫操作。

1.3. MemStore 刷寫策略(FlushPolicy)

在 HBase 1.1 之前,MemStore 刷寫是 Region 級別的。就是說,如果要刷寫某個 MemStore ,MemStore 所在的 Region 中其他 MemStore 也是會被一起刷寫的。HBASE-10201/HBASE-3149引入列族級別的刷寫。我們可以通過 hbase.regionserver.flush.policy 參數(shù)選擇不同的刷寫策略。

目前 HBase 2.0.2 的刷寫策略全部都是實現(xiàn) FlushPolicy 抽象類的。并且自帶三種刷寫策略:

FlushAllLargeStoresPolicy、FlushNonSloppyStoresFirstPolicy 以及 FlushAllStoresPolicy。

1.3.1 FlushAllStoresPolicy

返回當(dāng)前 Region 對應(yīng)的所有 MemStore。也就是每次刷寫都是對 Region 里面所有的 MemStore 進行的,這個行為和 HBase 1.1 之前是一樣的。

1.3.2 FlushAllLargeStoresPolicy

在 HBase 2.0 之前版本是 FlushLargeStoresPolicy,后面被拆分成分 FlushAllLargeStoresPolicyFlushNonSloppyStoresFirstPolicy,參見 HBASE-14920。

//region.getMemStoreFlushSize() / familyNumber
//就是 hbase.hregion.memstore.flush.size 參數(shù)的值除以相關(guān)表列族的個數(shù)
flushSizeLowerBound = max(region.getMemStoreFlushSize() / familyNumber, hbase.hregion.percolumnfamilyflush.size.lower.bound.min)
 
//如果設(shè)置了 hbase.hregion.percolumnfamilyflush.size.lower.bound
flushSizeLowerBound = hbase.hregion.percolumnfamilyflush.size.lower.bound

這種策略會先判斷 Region 中每個 MemStore 的使用內(nèi)存(OnHeap + OffHeap)是否大于某個閥值,大于這個閥值的 MemStore 將會被刷寫。閥值的計算是由 hbase.hregion.percolumnfamilyflush.size.lower.bound 、hbase.hregion.percolumnfamilyflush.size.lower.bound.min 以及 hbase.hregion.memstore.flush.size 參數(shù)決定的

hbase.hregion.percolumnfamilyflush.size.lower.bound.min 默認(rèn)值16MB
hbase.hregion.percolumnfamilyflush.size.lower.bound 默認(rèn)沒有設(shè)置。

比如當(dāng)前表有3個列族,其他用默認(rèn)的值,那么 flushSizeLowerBound = max((long)128 / 3, 16) = 42。

如果當(dāng)前 Region 中沒有 MemStore 的使用內(nèi)存大于上面的閥值,FlushAllLargeStoresPolicy 策略就退化成 FlushAllStoresPolicy 策略了,也就是會對 Region 里面所有的 MemStore 進行 Flush。

1.3.3 FlushNonSloppyStoresFirstPolicy

HBase 2.0 引入了 in-memory compaction,參見 HBASE-13408

如果我們對相關(guān)列族 hbase.hregion.compacting.memstore.type 參數(shù)的值不是 NONE,那么這個 MemStore 的 isSloppyMemStore 值就是 true,否則就是 false。

FlushNonSloppyStoresFirstPolicy 策略將 Region 中的 MemStore 按照 isSloppyMemStore 分到兩個 HashSet 里面(sloppyStoresregularStores)。然后

  • 判斷 regularStores 里面是否有 MemStore 內(nèi)存占用大于相關(guān)閥值的 MemStore ,有的話就會對這些 MemStore 進行刷寫,其他的不做處理,這個閥值計算和 FlushAllLargeStoresPolicy 的閥值計算邏輯一致。
  • 如果 regularStores 里面沒有 MemStore 內(nèi)存占用大于相關(guān)閥值的 MemStore,這時候就開始在 sloppyStores 里面尋找是否有 MemStore 內(nèi)存占用大于相關(guān)閥值的 MemStore,有的話就會對這些 MemStore 進行刷寫,其他的不做處理。
  • 如果上面 sloppyStoresregularStores 都沒有滿足條件的 MemStore 需要刷寫,這時候就 FlushNonSloppyStoresFirstPolicy 策略久退化成 FlushAllStoresPolicy 策略了。
HBase memstore flush from ali.jpeg

(圖片來源:阿里開發(fā)者社區(qū)

2. StoreFile Compaction

由于memstore每次刷寫都會生成一個新的HFile,且同一個字段的不同版本(timestamp)和不同類型(Put/Delete)有可能會分布在不同的HFile中,因此查詢時需要遍歷所有的HFile。為了減少HFile的個數(shù),以及清理掉過期和刪除的數(shù)據(jù),會進行StoreFile Compaction。

Compaction與Flush不同之處在于:Flush是針對一個Region整體執(zhí)行操作,而Compaction操作是針對Region上的一個Store而言,從邏輯上看,F(xiàn)lush操作粒度較大。

2.1 Minor Compaction 、Major Compaction

Compaction分為兩種,分別是Minor CompactionMajor Compaction

Minor Compaction會將臨近的若干個較小的HFile合并成一個較大的HFile,但不會清理過期和刪除的數(shù)據(jù)。

Major Compaction會將一個Store下的所有的HFile合并成一個大HFile,并且會清理掉過期和刪除的數(shù)據(jù)。

HBase StoreFile Compaction.png

2.2 Compaction 觸發(fā)條件

2.2.1 Memstore Flush

在進行Memstore Flush前后都會進行判斷是否觸發(fā)Compact。

flush之前,先判斷該region上是否有store中的hfile文件個數(shù)大于hbase.hstore.blockingStoreFiles,有則觸發(fā)compact操作。

flush之后,對當(dāng)前store中的文件數(shù)進行判斷,是否滿足規(guī)定的觸發(fā)條件,滿足則觸發(fā)compaction操作。

具體的代碼查看:MemStoreFlusher.flushRegion()方法。

2.2.2 定期檢查線程

周期性檢查是否需要進行compaction操作,周期為:hbase.server.thread.wakefrequency*hbase.server.compactchecker.interval.interval.multiplier

參數(shù)hbase.server.thread.wakefrequency默認(rèn)值 10000 即 10s,是HBase服務(wù)端線程喚醒時間間隔,用于log roller、memstore flusher等操作周期性檢查;

參數(shù) hbase.server.compactchecker.interval.multiplier默認(rèn)值1000,是compaction操作周期性檢查乘數(shù)因子。

具體的代碼查看:CompactionChecker.chore()方法。

2.2.3 手動執(zhí)行Compaction命令

手動觸發(fā)大多都是major compaction,避開業(yè)務(wù)高峰期進行major compaction,或修改了表的屬性需要立即生效,或需要物理刪除已刪除的數(shù)據(jù)和過期的數(shù)據(jù)。

HBase Shell、Master UI者HBase API 執(zhí)行 compact、major_compact等命令。

2.3 Compaction 參數(shù)解析

為了達到選擇盡量多的合并小文件的同時也減少IO,同時合并這些文件之后對讀的性能會有顯著的提升。

compaction源碼入口可以從CompactSplitThread.requestCompactionInternal方法進行查看。

首先都會對store上的hfile進行逐一排查,排除不滿足條件的文件,條件如下:

? a. 排除正在進行compaction的文件以及比這些文件更新的文件。

? b. 排除hfile大小大于hbase.hstore.compaction.max.size或在高峰期時大于hbase.hstore.compaction.max.size.offpeak的hfile。

滿足了條件的文件再通過策略去判斷是否滿足以下的Compaction 相關(guān)參數(shù),再作是否需要compact。

2.3.1 Major Compaction 參數(shù)

Major Compaction涉及的參數(shù)比較少,主要有大合并時間間隔與一個抖動參數(shù)因子

hbase.hregion.majorcompaction 默認(rèn)值604800000,單位ms Major compaction周期性時間間隔 
HBase 0.96.x及之前默認(rèn)為1天 設(shè)置為 0 時表示禁用自動觸發(fā)major compaction

hbase.hregion.majorcompaction.jitter 默認(rèn)值0.5 抖動參數(shù)
為了避免major compaction同時在各個regionserver上同時發(fā)生,避免此操作給集群帶來很大壓力

2.3.2 Minor Compaction 參數(shù)

Minor compaction涉及的參數(shù)比major compaction要多,各個參數(shù)的目標(biāo)是為了選擇合適的HFile

hbase.hstore.compaction.min :默認(rèn)值 3 早期參數(shù)名稱為 hbase.hstore.compactionthreshold。
表示進行compaction最少的hfile文件數(shù)。

hbase.hstore.compaction.max : 默認(rèn)值 10
一次minor compaction最多合并的HFile數(shù)量。

hbase.hstore.compaction.min.size :默認(rèn)值 128M(memstore flush size)
進行compaction的最小hfile大小,小于該值的hfile會直接被放入候選文件中。

hbase.hstore.compaction.max.size :默認(rèn)值Long.MAX_VALUE
進行compaction的最大hfile大小,大于該值的hfile不會被放入候選文件中。

hbase.hstore.compaction.ratio :默認(rèn)值1.2
進行compaction的ratio。

hbase.hstore.compaction.ratio.offpeak : 默認(rèn)值5.0
非高峰期的ratio控制
這個參數(shù)受另外兩個參數(shù) hbase.offpeak.start.hour 與 hbase.offpeak.end.hour 控制,這兩個參數(shù)值為[0, 23]的整數(shù),用于定義非高峰期時間段,默認(rèn)值均為-1表示禁用非高峰期ratio設(shè)置。

2.4 Compaction 策略介紹

HBase的compaction policy準(zhǔn)確的說有4種,分別是RatioBasedCompactionPolicy、ExploringCompactionPolicy、FIFOCompactionPolicy 以及 StripeCompactionPolicy。

其中,HBase使用的壓縮策略主要就是前兩種,HBase 0.96.x版本之前,默認(rèn)的壓縮策略是RatioBasedCompactionPolicy,HBase 0.96.x以及更新版本中,默認(rèn)為ExploringCompactionPolicy。

ExploringCompactionPoliy要比舊版本中的RatioBasedCompactionPolicy 性能更高,因此一般情況下也不建議改變默認(rèn)配置。

2.5 Compaction對于讀寫操作的影響

2.5.1 存儲上的寫入放大

HBase Compaction會帶來寫入放大,特別是在寫多讀少的場景下,寫入放大就會比較明顯。

下圖簡單示意了寫入放大的效果。

(圖片來源:https://mmbiz.qpic.cn/mmbiz_png/licvxR9ib9M6D6sDjXPZxHR1ic4LDKyicf2qfx417fJ8QHmfn82uBhSS1fC4mDqSB67JHzGs6kyqHiccrQEu2ryPKJA/640

隨著minor compaction以及major Compaction的發(fā)生,可以看到,這條數(shù)據(jù)被反復(fù)讀取/寫入了多次,這是導(dǎo)致寫放大的一個關(guān)鍵原因,這里的寫放大,涉及到網(wǎng)絡(luò)IO與磁盤IO,因為數(shù)據(jù)在HDFS中默認(rèn)有三個副本。

2.5.2 讀路徑上的延時毛刺

HBase執(zhí)行compaction操作結(jié)果會使文件數(shù)基本穩(wěn)定,進而IO Seek次數(shù)相對穩(wěn)定,延遲就會穩(wěn)定在一定范圍。然而,compaction操作會帶來很大的帶寬壓力以及短時間IO壓力。因此compaction就是使用短時間的IO消耗以及帶寬消耗換取后續(xù)查詢的低延遲。這種短時間的壓力就會造成讀請求在延時上會有比較大的毛刺。

下圖是一張示意圖,可見讀請求延時有很大毛刺,但是總體趨勢基本穩(wěn)定。

讀路徑上的延時毛刺.png

(圖片來源:http://img0.tuicool.com/3m2aIjv.png

2.5.3 寫請求上的短暫阻塞

Compaction對寫請求也會有比較大的影響。主要體現(xiàn)在HFile比較多的場景下,HBase會限制寫請求的速度。如果底層HFile數(shù)量超過hbase.hstore.blockingStoreFiles 配置值,默認(rèn)10,flush操作將會受到阻塞,阻塞時間為hbase.hstore.blockingWaitTime,默認(rèn)90000,即1.5分鐘,在這段時間內(nèi),如果compaction操作使得HFile下降到blockingStoreFiles配置值,則停止阻塞。另外阻塞超過時間后,也會恢復(fù)執(zhí)行flush操作。這樣做可以有效地控制大量寫請求的速度,但同時這也是影響寫請求速度的主要原因之一。

2.6 Compaction 總結(jié)

HBase Compaction操作是為了數(shù)據(jù)讀取做的優(yōu)化,總的來說是以犧牲磁盤io來換取讀性能的基本穩(wěn)定。Compaction操作分為minor compaction與major compaction,其中major compaction消耗資源較大、對讀寫請求有一定影響,因此一般是禁用自動周期性執(zhí)行而選擇業(yè)務(wù)低峰期時手動執(zhí)行。

HBase column family HStore compact from ali.jpeg

(圖片來源:阿里開發(fā)者社區(qū)

3. Region Split

默認(rèn)情況下,每個Table起初只有一個Region,隨著數(shù)據(jù)的不斷寫入,達到一定的大小Region會自動進行Split。剛拆分時,兩個子Region都位于當(dāng)前的Region Server,但處于負(fù)載均衡的考慮,HMaster有可能會將某個Region轉(zhuǎn)移給其他的Region Server。table在region中是按照row key來排序的,并且一個row key所對應(yīng)的行只會存儲在一個region中,這一點保證了Hbase的強一致性 。

在一個region中有一個或多個stroe,每個stroe對應(yīng)一個column families(列族)。一個store中包含一個memstore 和 0 或 多個store files。每個column family 是分開存放和分開訪問的。

注意,Region Split 是針對所有的列族進行的,這樣做的目的是同一行的數(shù)據(jù)即使在 Split 后也是存在同一個 Region 的。

3.1 Region Split時機

  1. 當(dāng)1個region中的某個Store下所有StoreFile的總大小超過hbase.hregion.max.filesize,該Region就會進行拆分(0.94版本之前)。

  2. 當(dāng)1個region中的某個Store下所有StoreFile的總大小超過Min(R^2 * hbase.hregion.memstore.flush.size,hbase.hregion.max.filesize"),該Region就會進行拆分,其中R為當(dāng)前Region Server中屬于該Table的個數(shù)(0.94版本之后)。

3.2 split的三種方式

3.2.1 Pre-splitting

當(dāng)一個table剛被創(chuàng)建的時候,Hbase默認(rèn)的分配一個region給table。也就是說這個時候,所有的讀寫請求都會訪問到同一個regionServer的同一個region中,這個時候就達不到負(fù)載均衡的效果了,集群中的其他regionServer就可能會處于比較空閑的狀態(tài)。解決這個問題可以用pre-splitting,在創(chuàng)建table的時候就配置好,生成多個region。

Hbase自帶了兩種pre-split的算法,分別是 HexStringSplitUniformSplit 。如果我們的row key是十六進制的字符串作為前綴的,就比較適合用HexStringSplit,作為pre-split的算法。例如,我們使用HexHash(prefix)作為row key的前綴,其中Hexhash為最終得到十六進制字符串的hash算法。我們也可以用我們自己的split算法。

hbase shell

hbase> hbase org.apache.hadoop.hbase.util.RegionSplitter pre_split_table HexStringSplit -c 10 -f f1

-c 10 的意思為,最終的region數(shù)目為10個;-f  f1為創(chuàng)建一個那么為f1的 column family.
hbase> scan 'hbase:meta'
scan hbase_meta.png

只截取了meta表中的2個region的記錄(一共10個region),分別是rowkey范圍是 '' ''~19999999 和19999999~33333332的region。

也可以自定義切分點,例如在hbase shell下使用如下命令:

hbase> create 't1', 'f1', {SPLITS => ['10', '20', '30', '40']}

或者

$ echo -e  "anbnc" >/tmp/splits
hbase(main):015:0> create 'test_table', 'f1', SPLITSFILE=>'/tmp/splits'

3.2.2 自動splitting

當(dāng)一個reion達到一定的大小,他會自動split稱兩個region。

Hbase版本是0.94 ,那么默認(rèn)的有三種自動split的策略,ConstantSizeRegionSplitPolicy,IncreasingToUpperBoundRegionSplitPolicy還有 KeyPrefixRegionSplitPolicy

在0.94版本之前ConstantSizeRegionSplitPolicy 是默認(rèn)和唯一的split策略。當(dāng)某個store(對應(yīng)一個column family)的大小大于配置值 ‘hbase.hregion.max.filesize’的時候(默認(rèn)10G)region就會自動分裂。

而0.94版本中,IncreasingToUpperBoundRegionSplitPolicy 是默認(rèn)的split策略。

這個策略中,最小的分裂大小和table的某個RegionServer的region 個數(shù)有關(guān),當(dāng)store file的大小大于如下公式得出的值的時候就會split,公式如下

Min (R的立方^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”)  

R為同一個table中在同一個region server中region的個數(shù)。

可以通過配置hbase.regionserver.region.split.policy來指定split策略,我們也可以寫我們自己的split策略。

3.2.3 強制split

Hbase 允許客戶端強制執(zhí)行split,在hbase shell中執(zhí)行以下命令:

 hbase> split 'forced_table', 'b' 
 
 //其中forced_table 為要split的table , ‘b’ 為split 點

HBase region splitfrom ali.jpeg

(圖片來源:阿里開發(fā)者社區(qū)

MemStore Flush參考

HBASE-10201

HBASE-3149

HBASE-5349

http://lxw1234.com/archives/2016/09/719.htm

[過往記憶]](https://www.iteblog.com/archives/2497.html#_MemStore)

compaction參考

http://www.itdecent.cn/p/eef5dc6f3cf4

https://blog.csdn.net/u011598442/article/details/90632702

http://hbase.apache.org/book.html#compaction
https://mp.weixin.qq.com/s/ctnCm3uLCotgRpozbXmVMg
https://blog.csdn.net/cangencong/article/details/72763265
https://blog.csdn.net/shenshouniu/article/details/83902291

Region Splitting 參考

https://blog.cloudera.com/apache-hbase-region-splitting-and-merging/

參考 https://developer.aliyun.com/article/73490

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容