HBase Memstore資料刷寫與阻塞機制深入剖析及引數優化-OLAP商業環境實戰
本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。版權宣告:禁止轉載,歡迎學習。QQ郵箱地址:[email protected],如有任何學術交流,可隨時聯絡。
網上的Hbase調優資料參差不齊,實在是不忍卒讀,有些都是拼湊且版本過時的東西,我這裡決定綜合所有優質資源進行整合,寫一份最全,最有深度,不過時的技術部落格。辛苦成文,各自珍惜,謝謝!版權宣告:禁止轉載,歡迎學習
1 Memstore的角色地位
- 一個Store中總會有一個Memstore和多個HFile,每一次刷寫就會生成一個HFile。
- 如果你開啟了BlcokCache,那麼讀取資料時會首先查詢BlockCache,當BlockCache查不到資料時,就會去查詢MemStore+HFile的資料。
- 這裡要明確一下,完整的資料集合包含了MemStore中的資料和落盤的HFile檔案。
- MemStore的實現目的不是加速資料的寫入,主要是維持HBase中的資料按照rowkey順序來儲存,所以先使用MemStore先對資料進行整理排序後再持久化到HDFS。

2 Memstore的各種阻塞
- 經常會遇到效能問題,寫操作被Block住了,其實大部分情況只要瞭解MemStore的刷寫機制和HFile的合併機制後,就可以著手解決寫操作被Block住的問題。
2.1 資料刷寫時機一(hbase.hregion.memstore.flush.size)
-
當Memstore佔用的記憶體大小達到hbase.hregion.memstore.flush.size的配置值得時候就會觸發一次刷寫,生產一個HFile。
悖論 :但是問題來了,因為MemStore的刷寫存在一個定期檢查時間,有時候可能資料增長速度太快,在還未達到檢查時間之前,資料就達到了hbase.hregion.memstore.flush.size的好幾倍,從而被阻塞住了。
2.2 memstore阻塞情況一
- hbase.hregion.memstore.flush.size 預設閾值是128MB
- hbase.hregion.memstore.block.multiplier:是一個倍數,預設是4。
上面兩個數的乘積預設為512M,因為MemStore的刷寫存在一個定期檢查時間,在下一次刷寫檢查到來之前若達到了這個閾值,就會立即觸發刷寫,同時阻塞住所有的寫入該Store的寫請求。
2.3 資料刷寫時機二 (globalMemStoreSize)
-
globalMemStoreLimitLowMarPercent:
全域性的memstore刷寫下限,過去通過配置hbase.regionserver.global.memstore.lowerLimit來定義,現在統一改成: hbase.regionserver.global.memstore.size.lower.limit。該配置項是一個百分比,所以取值在0.0-1.0,預設是0.95。
-
globalMemStoreSize表示全域性memstore容量,這個值計算方法如下:
hbase_heapsize(Regionserver 佔用堆記憶體大小)*hbase.regionserver.global.memstore.size 複製程式碼
hbase.regionserver.global.memstore.size的預設值是0.4,一旦達到這個閾值,就會觸發一次強制的刷寫。
2.4 memstore阻塞情況二(global.memstore.size):
當hbase_heapsize(Regionserver 佔用堆記憶體大小)*hbase.regionserver.global.memstore.size 大小達到閾值時,就會阻塞整個HBase叢集的寫入。
舉例:hBase堆記憶體的大小為16GB,hbase.regionserver.global.memstore.size是0.4 ,hbase.regionserver.global.memstore.lowerLimit為0.95 ,那麼觸發刷寫的閾值為: 16*0.4*0.95=6.08 舉例:hBase堆記憶體的大小為16GB,hbase.regionserver.global.memstore.size是 0.4,hbase.regionserver.global.memstore.lowerLimit為0.95 那麼觸發阻塞的閾值為: 16*0.4=6.4 真實案例:hbase_heapsize(Regionserver 佔用堆記憶體大小)配置太小,資料沒怎麼寫入就出現寫不進去了。 複製程式碼
2.5 資料刷寫時機三 (WAL的數量大於maxLogs)
WAL的數量大於maxLogs時,也會觸發一次刷寫,不過不會發生阻塞事件,倒是會警告一下。該引數其實新版本已經不需要進行設定了,最大就是32,也可以更小,根據hbase.regionserver.global.memstore.size來決定:
Math.max(32,(regionserverHeapSize*memstoreSizeRatio*2/logRollSize)) 複製程式碼
2.6 資料刷寫時機四(自動刷寫間隔)
hbase.regionserver.optionalcacheflushinterval:表示memstore的刷寫間隔,預設值是3600000,即1個小時。如果設定為0,則意味著關閉自動刷寫。