HBase源码分析之MemStore的flush发起时机、判断条件等详情

        前面的几篇文章,我们详细介绍了HBase中HRegion上MemStore的flsuh流程,以及HRegionServer上MemStore的flush处理流程。那么,flush到底是在什么情况下触发的呢?本文我们将详细探究下HBase中MemStore的flush流程的发起时机,看看到底都有哪些操作,或者哪些后台服务进程会触发MemStore的flush。

        首先,在《HBase源码分析之HRegionServer上MemStore的flush处理流程(一)》《HBase源码分析之HRegionServer上MemStore的flush处理流程(二)》两篇文章中,我们了解了HRegionServer上MemStore的flush处理流程,知道了这么一个事实:flush的请求会通过requestFlush()或requestDelayedFlush()方法被添加到MemStoreFlusher的flushQueue队列中,然后由其内部的FlushHandler线程组消费,对需要flush的HRegion进行处理。所以,我们首先可以知道,调用MemStoreFlusher这两个方法的地方,肯定就会是MemStore发起flush的部分时机,另外,或许会存在部分操作或者内部流程直接调用HRegion的flushcache()方法而触发flush。下面,我们开始总结下,都有哪些操作或者内部流程触发MemStore的flush,以及需要flush的判断条件,包括其他一些方面的详情。

        一、通过将RequestFlush请求添加到MemStoreFlusher的flushQueue队列

        (一)单个Put操作

        在HRegion中处理Put操作的put(Put put)方法中,在开始执行操作前,首先会调用checkResources()方法检查资源,这个checkResources()实际上就是检查HRegion的MemStore大小是否超过一定的阈值,如果超过,则会调用requestFlush()方法发起对该HRegion的MemStore进行flush的请求,并抛出RegionTooBusyException异常,阻止该操作继续,后续将要讲的Delete、Append等数据更新操作也是如此,在开始执行操作前都会调用这个checkResources()方法来检查资源。checkResources()方法代码如下:

/*
   * Check if resources to support an update.
   * 检测是否有足够的资源支持一个Put、Append等数据更新操作
   *
   * We throw RegionTooBusyException if above memstore limit
   * and expect client to retry using some kind of backoff
   * 如果超过memstore的限制,我们抛出RegionTooBusyException这个异常,并且期望客户端使用某种补偿进行重试
  */
  private void checkResources()
    throws RegionTooBusyException {
    // If catalog region, do not impose resource constraints or block updates.
	// 如果是Meta Region,不实施资源约束或阻塞更新
    if (this.getRegionInfo().isMetaRegion()) return;

    // 如果Region当前内存大小超过阈值
    // 这个memstoreSize是当前时刻HRegion上MemStore的大小,它是在Put、Append等操作中调用addAndGetGlobalMemstoreSize()方法实时更新的。
    // 而blockingMemStoreSize是HRegion上设定的MemStore的一个阈值,当MemStore的大小超过这个阈值时,将会阻塞数据更新操作
    if (this.memstoreSize.get() > this.blockingMemStoreSize) {
      // 更新阻塞请求计数器
      blockedRequestsCount.increment();
      // 请求刷新Region
      requestFlush();
      
      // 抛出RegionTooBusyException异常
      throw new RegionTooBusyException("Above memstore limit, " +
          "regionName=" + (this.getRegionInfo() == null ? "unknown" :
          this.getRegionInfo().getRegionNameAsString()) +
          ", server=" + (this.getRegionServerServices() == null ? "unknown" :
          this.getRegionServerServices().getServerName()) +
          ", memstoreSize=" + memstoreSize.get() +
          ", blockingMemStoreSize=" + blockingMemStoreSize);
    }
  }
        首先,如果是Meta Region,不实施资源约束或阻塞更新;

        然后,如果Region当前内存大小memstoreSize超过阈值blockingMemStoreSize,则更新阻塞请求计数器,发起刷新MemStore请求,并抛出RegionTooBusyException异常,阻塞数据更新操作。

        我们首先来看下memstoreSize,这个memstoreSize是当前时刻HRegion上MemStore的大小,它是在Put、Append等操作中调用addAndGetGlobalMemstoreSize()方法实时更新的。代码如下:

  /**
   * Increase the size of mem store in this region and the size of global mem
   * store
   * @return the size of memstore in this region
   */
  public long addAndGetGlobalMemstoreSize(long memStoreSize) {
    if (this.rsAccounting != null) {
      rsAccounting.addAndGetGlobalMemstoreSize(memStoreSize);
    }
    return this.memstoreSize.addAndGet(memStoreSize);
  }
        而blockingMemStoreSize是HRegion上设定的MemStore的一个阈值,当MemStore的大小超过这个阈值时,将会阻塞数据更新操作。其定义在HRegion上线被构造时需要调用的一个setHTableSpecificConf()中,部分代码如下&
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值