溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

HBase – Memstore Flush和flush shell操作 深度解析

發(fā)布時(shí)間:2020-06-28 14:39:28 來(lái)源:網(wǎng)絡(luò) 閱讀:740 作者:馬吉輝 欄目:大數(shù)據(jù)

//memstore flush機(jī)制 和flush shell命令刷新
//Memstore是HBase框架中非常重要的組成部分之一,是HBase能夠?qū)崿F(xiàn)高性能隨機(jī)讀寫至關(guān)重要的一環(huán)。深入理解Memstore的工作原理、運(yùn)行機(jī)制以及相關(guān)配置,對(duì)hbase集群管理、性能調(diào)優(yōu)都有著非常重要的幫助。

寫機(jī)制(大約)
1、HBase是基于LSM-Tree模型的,
2、所有的數(shù)據(jù)更新插入操作都首先寫入Memstore中(同時(shí)會(huì)順序?qū)懙饺罩綡Log中),
3、達(dá)到指定大小之后再將這些修改操作批量寫入磁盤,生成一個(gè)新的HFile文件,這種設(shè)計(jì)可以極大地提升HBase的寫入性能;
4、HBase為了方便按照RowKey進(jìn)行檢索,要求HFile中數(shù)據(jù)都按照RowKey進(jìn)行排序,
5、Memstore數(shù)據(jù)在flush為HFile之前會(huì)進(jìn)行一次排序,將數(shù)據(jù)有序化;

讀機(jī)制(大約)
1、根據(jù)局部性原理,新寫入的數(shù)據(jù)會(huì)更大概率被讀取,
2、因此HBase在讀取數(shù)據(jù)的時(shí)候首先檢查請(qǐng)求的數(shù)據(jù)是否在Memstore,
3、寫緩存未命中的話再到讀緩存中查找,讀緩存還未命中才會(huì)到HFile文件中查找,最終返回merged的一個(gè)結(jié)果給用戶。

//可見,Memstore無(wú)論是對(duì)HBase的寫入性能還是讀取性能都至關(guān)重要。其中flush操作又是Memstore最核心的操作。

問(wèn)題:
接下來(lái)重點(diǎn)針對(duì)Memstore的flush操作進(jìn)行深入地解析:
1、首先分析HBase在哪些場(chǎng)景下會(huì)觸發(fā)flush,
2、然后結(jié)合源代碼分析整個(gè)flush的操作流程。
3、最后再重點(diǎn)整理總結(jié)和flush相關(guān)的配置參數(shù),這些參數(shù)對(duì)于性能調(diào)優(yōu)、問(wèn)題定位都非常重要。

HBase會(huì)在如下幾種情況下觸發(fā)flush操作?
//提示:
需要注意的是MemStore的最小flush單元是HRegion而不是單個(gè)MemStore。 //這就話可以理解Wie:
當(dāng)一個(gè)region是2個(gè)列族的時(shí)候,就會(huì)有2個(gè)memstore 比如如果其中一個(gè)menstore=128M了,另一個(gè)沒(méi)有達(dá)到128M 不會(huì)flush
只有當(dāng)region中的2個(gè)memstore都達(dá)到了128M的時(shí)候,才會(huì)觸發(fā)真正的刷新region級(jí)別的flush
可想而知,如果一個(gè)HRegion中Memstore過(guò)多,每次flush的開銷必然會(huì)很大,因此我們也建議在進(jìn)行表設(shè)計(jì)的時(shí)候盡量減少ColumnFamily的個(gè)數(shù)。建議列族為1-3個(gè),熱門業(yè)務(wù)的列族就設(shè)計(jì)成1個(gè)
1、Memstore級(jí)別限制:當(dāng)Region中任意一個(gè)MemStore的大小達(dá)到了上限(hbase.hregion.memstore.flush.size,默認(rèn)128MB),會(huì)觸發(fā)Memstore刷新。
2、Region級(jí)別限制:當(dāng)Region中所有Memstore的大小總和達(dá)到了上限(hbase.hregion.memstore.block.multiplier hbase.hregion.memstore.flush.size,默認(rèn) 2 128M = 256M),會(huì)觸發(fā)memstore刷新。
3、Region Server級(jí)別限制:當(dāng)一個(gè)Region Server中所有Memstore的大小總和達(dá)到了上限 (hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默認(rèn) 40%的JVM內(nèi)存使用量),會(huì)觸發(fā)部分Memstore刷新。Flush順序是按照Memstore由大到小執(zhí)行,先Flush Memstore最大的Region,再執(zhí)行次大的,直至總體Memstore內(nèi)存使用量低于閾值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默認(rèn) 38%的JVM內(nèi)存使用量)。
//影響很大
4、當(dāng)一個(gè)Region Server中HLog數(shù)量達(dá)到上限(可通過(guò)參數(shù)hbase.regionserver.maxlogs配置)時(shí),系統(tǒng)會(huì)選取最早的一個(gè) HLog對(duì)應(yīng)的一個(gè)或多個(gè)Region進(jìn)行flush
5、HBase定期刷新Memstore:默認(rèn)周期為1小時(shí),確保Memstore不會(huì)長(zhǎng)時(shí)間沒(méi)有持久化。為避免所有的MemStore在同一時(shí)間都進(jìn)行flush導(dǎo)致的問(wèn)題,定期的flush操作有20000左右的隨機(jī)延時(shí)。
6、手動(dòng)執(zhí)行flush:用戶可以通過(guò)shell命令 flush ‘tablename’或者flush ‘region name’分別對(duì)一個(gè)表或者一個(gè)Region進(jìn)行flush。
//6種方式可以觸發(fā) flush的操作,以上參數(shù)在cdh中都有

Memstore Flush流程 //具體見博客
為了減少flush過(guò)程對(duì)讀寫的影響,HBase采用了類似于兩階段提交的方式,將整個(gè)flush過(guò)程分為三個(gè)階段:
1、prepare階段
(1)遍歷當(dāng)前Region中的所有Memstore,將Memstore中當(dāng)前數(shù)據(jù)集kvset做一個(gè)快照snapshot,然后再新建一個(gè)新的kvset。
(2)后期的所有寫入操作都會(huì)寫入新的kvset中,而整個(gè)flush階段讀操作會(huì)首先分別遍歷kvset和snapshot,如果查找不到再會(huì)到HFile中查找。
(3)prepare階段需要加一把updateLock對(duì)寫請(qǐng)求阻塞,結(jié)束之后會(huì)釋放該鎖。
(4)因?yàn)榇穗A段沒(méi)有任何費(fèi)時(shí)操作,因此持鎖時(shí)間很短
2、flush階段
(1)遍歷所有Memstore,將prepare階段生成的snapshot持久化為臨時(shí)文件,臨時(shí)文件會(huì)統(tǒng)一放到目錄.tmp下。
(2)這個(gè)過(guò)程因?yàn)樯婕暗酱疟PIO操作,因此相對(duì)比較耗時(shí)。
3、commit階段
(1)遍歷所有的Memstore,將flush階段生成的臨時(shí)文件移到指定的ColumnFamily目錄下,
(2)針對(duì)HFile生成對(duì)應(yīng)的storefile和Reader,把storefile添加到HStore的storefiles列表中,
(3)最后再清空prepare階段生成的snapshot。

Memstore Flush對(duì)業(yè)務(wù)讀寫的影響
1、想必對(duì)于HBase用戶來(lái)說(shuō),最關(guān)心的是flush行為會(huì)對(duì)讀寫請(qǐng)求造成哪些影響以及如何避免。
2、因?yàn)椴煌|發(fā)方式下的flush操作對(duì)用戶請(qǐng)求影響不盡相同,因此下面會(huì)根據(jù)flush的不同觸發(fā)方式分別進(jìn)行總結(jié),并且會(huì)根據(jù)影響大小進(jìn)行歸類:
(1)影響甚微
正常情況下,大部分Memstore Flush操作都不會(huì)對(duì)業(yè)務(wù)讀寫產(chǎn)生太大影響,比如這幾種場(chǎng)景:HBase定期刷新Memstore、手動(dòng)執(zhí)行flush操作、觸發(fā)Memstore級(jí)別限制、觸發(fā)HLog數(shù)量限制以及觸發(fā)Region級(jí)別限制等,這幾種場(chǎng)景只會(huì)阻塞對(duì)應(yīng)Region上的寫請(qǐng)求,阻塞時(shí)間很短,毫秒級(jí)別。

(2)影響較大
然而一旦觸發(fā)Region Server級(jí)別限制導(dǎo)致flush,就會(huì)對(duì)用戶請(qǐng)求產(chǎn)生較大的影響。會(huì)阻塞所有落在該Region Server上的更新操作,阻塞時(shí)間很長(zhǎng),甚至可以達(dá)到分鐘級(jí)別。一般情況下Region Server級(jí)別限制很難觸發(fā),但在一些極端情況下也不排除有觸發(fā)的可能,下面分析一種可能觸發(fā)這種flush操作的場(chǎng)景:
//
相關(guān)JVM配置以及HBase配置:

maxHeap = 71
hbase.regionserver.global.memstore.upperLimit = 0.35
hbase.regionserver.global.memstore.lowerLimit = 0.30

基于上述配置,可以得到觸發(fā)Region Server級(jí)別的總Memstore內(nèi)存和為24.9G,如下所示:

2015-10-12 13:05:16,232 INFO [regionserver60020] regionserver.MemStoreFlusher: globalMemStoreLimit=24.9 G, globalMemStoreLimitLowMark=21.3 G, maxHeap=71 G
//根據(jù)上面第3條件的設(shè)置
710.30~710.35 //就是region server當(dāng)memstore的內(nèi)存綜合趨于 21.3 24.85 高于24.85 就觸發(fā)flush 要低于 21.3

分析:
假設(shè)每個(gè)Memstore大小為默認(rèn)128M,在上述配置下如果每個(gè)Region有兩個(gè)Memstore,整個(gè)Region Server上運(yùn)行了100個(gè)region,根據(jù)計(jì)算可得總消耗內(nèi)存 = 128M 100 2 = 25.6G > 24.9G,很顯然,這種情況下就會(huì)觸發(fā)Region Server級(jí)別限制,對(duì)用戶影響相當(dāng)大。

小結(jié):
1、根據(jù)上面的分析,導(dǎo)致觸發(fā)Region Server級(jí)別限制的因素主要有一個(gè)Region Server上運(yùn)行的Region總數(shù),
2、一個(gè)是Region上的Store數(shù)(即表的ColumnFamily數(shù))。
3、對(duì)于前者,根據(jù)讀寫請(qǐng)求量一般建議線上一個(gè)Region Server上運(yùn)行的Region保持在50~80個(gè)左右,太小的話會(huì)浪費(fèi)資源,太大的話有可能觸發(fā)其他異常;
4、對(duì)于后者,建議ColumnFamily越少越好,如果從邏輯上確實(shí)需要多個(gè)ColumnFamily,最好控制在3個(gè)以內(nèi)。

小伙伴的問(wèn)題1:
一個(gè)查詢需要查一個(gè)Store中的mem和file。
如果發(fā)現(xiàn)block在blockcache中會(huì)去blockcache中讀取,就可以不需要去讀取那個(gè)file。
mem是肯定要被讀取(否則讀取的數(shù)據(jù)有問(wèn)題)。
cache和file兩者不一定,但是新生成的file如果沒(méi)有被讀取過(guò)肯定不在blockcache中。
答:
基本正確

小伙伴的問(wèn)題2:
在memstore flush 機(jī)制中 *****
4、當(dāng)一個(gè)Region Server中HLog數(shù)量達(dá)到上限(可通過(guò)參數(shù)hbase.regionserver.maxlogs配置)時(shí),系統(tǒng)會(huì)選取最早的一個(gè) HLog對(duì)應(yīng)的一個(gè)或多個(gè)Region進(jìn)行flush。
“一個(gè)Region Server中HLog數(shù)量” 不就只有一個(gè)嘛,為什么一個(gè)region server 的hlog數(shù)量之說(shuō),而且博主在“HBase - 數(shù)據(jù)寫入流程解析”里面也說(shuō)了“每個(gè)Region Server擁有一個(gè)HLog日志”。這邊描述是否有點(diǎn)問(wèn)題。不是很明白,還是博主解答。

答:
《HBase - 數(shù)據(jù)寫入流程解析》中說(shuō)到“每個(gè)Region Server擁有一個(gè)HLog日志”是想強(qiáng)調(diào)所有Region共用HLog。一個(gè)Region Server中所有Region都會(huì)向同一個(gè)HLog寫日志,當(dāng)HLog大小超過(guò)閾值就會(huì)新生成一個(gè)HLog文件接收新的寫入。所以HLog文件個(gè)數(shù)實(shí)際上有多個(gè)的。

小伙伴的問(wèn)題3:
因此HBase在讀取數(shù)據(jù)的時(shí)候首先檢查請(qǐng)求的數(shù)據(jù)是否在Memstore,寫緩存未命中的話再到讀緩存中查找,讀緩存還未命中才會(huì)到HFile文件中查找,
———————————————
你好!這里我有個(gè)疑問(wèn),假如我是scan查詢,寫緩存或者讀緩存只有部分?jǐn)?shù)據(jù)滿足要求,這時(shí)服務(wù)端是直接返回這部分?jǐn)?shù)據(jù),還是會(huì)繼續(xù)到HFile中查找
答:
全部查詢得到所有結(jié)果之后統(tǒng)一返回

參考鏈接: http://hbasefly.com/2016/03/23/hbase-memstore-flush/

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI