HBase源码分析之compact请求发起时机、判断条件等详情(一)

        一般说来,任何一个比较复杂的分布式系统,针对能够使得其性能得到大幅提升的某一内部处理流程,必然有一个定期检查机制,使得该流程在满足一定条件的情况下,能够自发的进行,这样才能够很好的体现出复杂系统的自我适应与自我调节能力。我们知道,HBase内部的compact处理流程是为了解决MemStore Flush之后,文件数目太多,导致读数据性能大大下降的一种自我调节手段,它会将文件按照某种策略进行合并,大大提升HBase的数据读性能。那么,基于我刚才的陈述,compact流程是否有一个定期检查机制呢?在满足什么条件的情况下,会触发compact请求呢?

        针对第一个问题,回答当然是肯定的。在HRegionServer内部,有一个成员变量,定义如下:

  /*
   * Check for compactions requests.
   * 检查合并请求
   */
  Chore compactionChecker;
         单从注释,我们就可以看出,这个compactionChecker成员变量就是一个检查合并请求的Chore,那么什么是Chore呢?先来看下它的定义、成员变量以及构造函数。先来看下类的定义,代码如下:

/**
 * Chore is a task performed on a period in hbase.  The chore is run in its own
 * thread. This base abstract class provides while loop and sleeping facility.
 * If an unhandled exception, the threads exit is logged.
 * Implementers just need to add checking if there is work to be done and if
 * so, do it.  Its the base of most of the chore threads in hbase.
 *
 * <p>Don't subclass Chore if the task relies on being woken up for something to
 * do, such as an entry being added to a queue, etc.
 * 
 * Chore是定期在HBase中执行的一个任务。Chore在它所在的线程内执行。这个基础抽象类提供了loop循环和sleep机制。
 */
@InterfaceAudience.Private
public abstract class Chore extends HasThread {
 
}
        首先,从类的定义我们可以看到,Chore继承自HasThread类,而HasThread类是一个实现了Runnable接口的抽象类,并且定义了一个抽象的run()方法。自然,Chore就是一个线程了。而通过注释,我们可以很清晰的知道以下三点:1、Chore是定期在HBase中执行的一个任务;2、Chore在它所在的线程内执行;3、这个基础抽象类提供了loop循环和sleep机制。

        再来看下它的成员变量,主要包含以下几个:

private final Sleeper sleeper;// 睡眠器
protected final Stoppable stopper;
        上面提到,Chore提供了sleep机制,那么这个机制就是依靠Sleeper类型的sleeper这个成员变量来实现的,而stopper则是实现了Stoppable接口的任何实例,实际上是工作线程所依附的可停止运行的载体,比如HRegionServer,载体停止运行后,工作线程。等到分析其run()方法时,我们再具体分析这两个变量。

        然后,我们再看下Chore的构造方法,代码如下:

  /**
   * @param p Period at which we should run.  Will be adjusted appropriately
   * should we find work and it takes time to complete.
   * @param stopper When {@link Stoppable#isStopped()} is true, this thread will
   * cleanup and exit cleanly.
   * 
   * 构造方法,需要name、p和stopper三个参数
   * p为run方法循环的周期
   * 
   */
  public Chore(String name, final int p, final Stoppable stopper) {
    super(name);
    if (stopper == null){
      throw new NullPointerException("stopper cannot be null");
    }
    this.sleeper = new Sleeper(p, stopper);
    this.stopper = stopper;
  }
        它需要name、p和stopper三个参数,name很简单,String类型的线程名字而已,关键在于这个int类型的p和Stoppable类型的stopper,构造函数利用p和stopper生成了一个睡眠期sleeper,并将stopper赋值给其同名成员变量。

        下面,我们来看下这个sleeper的实现吧!Sleeper类中定义了4个关键变量和两个关键方法,实现了一个简单的睡眠器,其4个关键成员变量如下:

  private final int period;
  private final Stoppable stopper;
  private final Object sleepLock = new Object();
  private boolean triggerWake = false;
        其中,period代表了睡眠周期,它是由上诉参数p赋值的,而stopper的含义与Chore中同名变量一样。sleepLock仅仅是一个Object对象,依靠它的wait()方法,我们可以实现对象等待一段时间;triggerWake是一个标志位,依靠它被设置为true,我们可以跳出睡眠,重新复苏。
        再来看下它的最终要的两个方法,第一个便是睡眠器最主要的功
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值