memstore的flush流程分析

memstoreflush流程分析

memstoreflush发起主要从以下几个地方进行:

a.HRegionServer调用multi进行更新时,检查是否超过全局的memstore配置的最大值与最小值,

如果是,发起一个WakeupFlushThreadflush请求,如果超过全局memory的最大值,需要等待flush完成。

b.HRegionServer进行数据更新时,调用HRegion.batchMutate更新store中数据时,

如果region.memstore的大小超过配置的regionmemstore size时,发起一个FlushRegionEntryflush请求,

c.client端显示调用HRegionServer.flushRegion请求

d.通过hbase.regionserver.optionalcacheflushinterval配置,

默认3600000msHRegionServer.PeriodicMemstoreFlusher定时flush线程


flush的执行过程

flush的具体执行通过MemStoreFlusher完成,当发起flushRequest时,

会把flushrequest添加到flushQueue队列中,同时把request添加到regionsInQueue列表中。

MemStoreFlusher实例生成时会启动MemStoreFlusher.FlushHandler线程实例,

此线程个数通过hbase.hstore.flusher.count配置,默认为1


privateclassFlushHandler extendsHasThread{

@Override

publicvoidrun(){

while(!server.isStopped()){

FlushQueueEntryfqe = null;

try{

wakeupPending.set(false);// allow someone to wake us up again

从队列中取出一个flushrequest,此队列是一个阻塞队列,如果flushQueue队列中没有值,

等待hbase.server.thread.wakefrequency配置的ms,默认为10*1000

fqe= flushQueue.poll(threadWakeFrequency,TimeUnit.MILLISECONDS);

if(fqe ==null|| fqeinstanceofWakeupFlushThread) {

如果没有flushrequest或者flushrequest是一个全局flushrequest

检查所有的memstore是否超过hbase.regionserver.global.memstore.lowerLimit配置的值,默认0.35

if(isAboveLowWaterMark()){

LOG.debug("Flushthread woke up because memory above low water="

              • StringUtils.humanReadableInt(globalMemStoreLimitLowMark));

超过配置的最小memstore的值,flsuh掉最大的一个memstoreregion

此执行方法的流程分析MemStoreFlusher.flushOneForGlobalPressure流程分析

if(!flushOneForGlobalPressure()){


....................此处部分代码没有显示


Thread.sleep(1000);

没有需要flushregion,叫醒更新线程的等待,

HregionServer执行数据更新的相关方法如果发现memstore的总和超过配置的最大值时,会wait更新线程,等待flush


wakeUpIfBlocking();

}

//Enqueue another one of these tokens so we'll wake up again

发起另一个叫醒的全局flushrequest,生成WakeupFlushThreadrequest

wakeupFlushThread();

}

continue;

}

正常的flushrequest,

单个regionmemstore大小超过hbase.hregion.memstore.flush.size配置的值,默认1024*1024*128L

此执行方法的流程分析见MemStoreFlusher.flushRegion

FlushRegionEntry fre= (FlushRegionEntry) fqe;

if(!flushRegion(fre)){

break;

}

} catch(InterruptedException ex){

continue;

} catch(ConcurrentModificationException ex){

continue;

} catch(Exception ex){

LOG.error("Cacheflusher failed for entry " + fqe,ex);

if(!server.checkFileSystem()){

break;

}

}

}

结束MemStoreFlusher的线程调用,通常是regionserverstop

synchronized(regionsInQueue){

regionsInQueue.clear();

flushQueue.clear();

}


//Signal anyone waiting, so they see the close flag

wakeUpIfBlocking();

LOG.info(getName()+ " exiting");

}

}


MemStoreFlusher.flushOneForGlobalPressure流程分析

此方法主要用来取出所有regionmemstore最大的一个region,并执行flush操作。


privatebooleanflushOneForGlobalPressure(){

SortedMap<Long,HRegion>regionsBySize=

server.getCopyOfOnlineRegionsSortedBySize();


Set<HRegion>excludedRegions= newHashSet<HRegion>();


booleanflushedOne= false;

while(!flushedOne){

//Find the biggest region that doesn't have too many storefiles

//(might be null!)

取出memstore占用最大的一个region,但这个region需要满足以下条件:

a.regionwritestate.flushing==false,同时writestate.writesEnabled==true,readonly

b.region中所有的store中的storefile的个数小于hbase.hstore.blockingStoreFiles配置的值,默认为7

此处去找region时,是按regionmemstore的大小从大到小排序组成。取出满足以上条件的最大的memstoreregion

如果都不满足,返回null

HRegion bestFlushableRegion= getBiggestMemstoreRegion(

regionsBySize,excludedRegions,true);

//Find the biggest region, total, even if it might have too manyflushes.

取出memstore占用最大的一个region,但这个region需要满足以下条件:

a.regionwritestate.flushing==false,同时writestate.writesEnabled==true,readonly

b.regionmemstore的大小从大到小排序组成。取出满足以上条件的最大的memstoreregion

如果都不满足,返回null,此处不检查region中是否有store的文件个数超过指定的配置值。

HRegion bestAnyRegion= getBiggestMemstoreRegion(

regionsBySize,excludedRegions,false);

如果没有拿到上面第二处检查的region,那么表示没有需要flushregion,返回,不进行flush操作。

if(bestAnyRegion== null){

LOG.error("Abovememory mark but there are no flushable regions!");

returnfalse;

}

得到最需要进行flushregion,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值