HBase-Compact-PressureAwareCompactionThroughputController分析

请求链路

配置

RegionServer启动的时候,初始化加载配置

参数

含义

下文简称

 

hbase.regionserver.throughput.controller对应的策略类 目前只有两种,一种限流,一种不限流
hbase.hstore.compaction.throughput.lower.bound非空闲期,一般为白天忙时的最低阈值lower单位B (逻辑流量) 默认10MB
hbase.hstore.compaction.throughput.higher.bound非空闲期,一般为白天忙时的最高阈值higher单位B (逻辑流量) 默认20MB 白天忙时流量阈值在lower和higher之间波动
hbase.offpeak.start.hour空闲期开始小时start hour例如 0
hbase.offpeak.end.hour空闲期结束小时end hour

例如 6 ,

1.06:00以后都不在offpeak的时间内

 

hbase.hstore.compaction.throughput.offpeakstart~end hour之间,空闲期的阈值
OffpeakLimitSize
单位B(逻辑流量) 默认:Long.MAX_VALUE 相当于不限流

 

阈值计算

1.计算当前RegionServer的compactPressure

PressureAwareCompactionThroughputController类中定期根据compactPressure计算实际流量阈值

每个HStore(一个region的其中一个列簇对应一个HStore)做下面计算,去这个机器上下面值最大的一个

计算逻辑

 


2.计算server级别的maxThroughput

compactPressure计算出来之后如何应用?

compactPressure > 1      ——说明现在hstore下文件数量大于 blockingfiles数量,已经出现阻塞flush的情况,写入内存的数据不能及时被持久化

       maxThroughput = Long.MAX_VALUE

else if ( 在offpeak start~end时间内 )

       maxThroughput=配置的OffpeakLimitSize

else  

       maxThroughput=lower + (higher - lower)  * compactionPressure;    —— 此时流量阈值在lower 和 higher之间随store下面文件数量 波动

 


3.计算每个compact的sleep时间,并进行sleep

每个compact 任务可用流量 =  maxThroughput /当前active compact 任务数量

允许的时长 = ( 当前compact 任务的delta size / 每个compact 任务可用流量 ) * 1000  (单位ms)

已经流失时长=当前时间-上次实际执行compact时间

 

if 已经流失时长 >= 允许的时长  不执行sleep
else sleepTime = 已经流失时长 - 允许的时长

 

 

 

 

 

PressureAwareCompactionThroughputController里面的tuneChore定期获取server.getCompactionPressure()
用来做流量的计算


获取本server上所有region的所有store,store.getCompactionPressure最大的一个


store.getCompactionPressure如何计算
  public double getCompactionPressure() {
    return storeEngine.getStoreFileManager().getCompactionPressure();
  }


  @Override
  public double getCompactionPressure() {
    int storefileCount = getStorefileCount();   //文件数量
    int minFilesToCompact = comConf.getMinFilesToCompact();    "hbase.hstore.compaction.min"  旧配置 “hbase.hstore.compactionThreshold” 未配置的为3
    if (storefileCount <= minFilesToCompact) {
      return 0.0;
    }


    //blockingFileCount = "hbase.hstore.blockingStoreFiles" 默认为7
    //这个公式含义:  现在可compact的文件数是否超过需要blocking的数量


    return (double) (storefileCount - minFilesToCompact) / (blockingFileCount - minFilesToCompact);
  }





  private void tune(double compactionPressure) {
    double maxThroughputToSet;


    // compactionPressure > 1.0  //超过了blocking File  不限流
    if (compactionPressure > 1.0) {
      // set to unlimited if some stores already reach the blocking store file count
      maxThroughputToSet = Double.MAX_VALUE;


      //  在空闲时间内
    } else if (offPeakHours.isOffPeakHour()) {
      maxThroughputToSet = maxThroughputOffpeak;
    } 


     //不在空闲时间内
    else {
      // compactionPressure is between 0.0 and 1.0, we use a simple linear formula to
      // calculate the throughput limitation.
      maxThroughputToSet =
          maxThroughputLowerBound + (maxThroughputHigherBound - maxThroughputLowerBound)
              * compactionPressure;
    }
    if (LOG.isDebugEnabled()) {
      LOG.debug("compactionPressure is " + compactionPressure + ", tune compaction throughput to "
          + throughputDesc(maxThroughputToSet));
    }
    this.maxThroughput = maxThroughputToSet;
  }



//=====================================================================================================


  @Override
  public long control(String compactionName, long size) throws InterruptedException {
    ActiveCompaction compaction = activeCompactions.get(compactionName);
    compaction.totalSize += size;//当前这个compact的size累加
    long deltaSize = compaction.totalSize - compaction.lastControlSize;  //变化的值

    //controlPerSize = max;  如果变化的值大于controlPerSize直接返回0
    if (deltaSize < controlPerSize) {
      return 0;
    }
    long now = EnvironmentEdgeManager.currentTimeMillis();

    //maxThroughputPerCompaction(每个compact 流量) = 机器compact流量最大值 / 当前活跃的Compact任务数量
    double maxThroughputPerCompaction = this.maxThroughput / activeCompactions.size();

    // 最小允许时间 = 本次需要的流量 / 每个compact可用流量 *1000 (    单位 ms)
    long minTimeAllowed = (long) (deltaSize / maxThroughputPerCompaction * 1000); // ms

    // 从上次触发control到这次的时间
    long elapsedTime = now - compaction.lastControlTime;
    compaction.lastControlSize = compaction.totalSize;

    //如果 已经经过的时间 大于 最小控制时间  (说明时间已经充足了,直接返回0)
    if (elapsedTime >= minTimeAllowed) {
      compaction.lastControlTime = EnvironmentEdgeManager.currentTimeMillis();
      return 0;
    }


    // 如果经过的时间,小于等于最小允许时间 说明:too fast
    // sleepTime  可允许的时间-已经等待的时间
    long sleepTime = minTimeAllowed - elapsedTime;
    if (LOG.isDebugEnabled()) {
      // do not log too much
      if (now - compaction.lastLogTime > 60L * 1000) {
        LOG.debug(compactionName + " sleep " + sleepTime + " ms because current throughput is "
            + throughputDesc(deltaSize, elapsedTime) + ", max allowed is "
            + throughputDesc(maxThroughputPerCompaction) + ", already slept "
            + compaction.numberOfSleeps + " time(s) and total slept time is "
            + compaction.totalSleepTime + " ms till now.");
        compaction.lastLogTime = now;
      }
    }
    Thread.sleep(sleepTime);
    compaction.numberOfSleeps++;
    compaction.totalSleepTime += sleepTime;
    compaction.lastControlTime = EnvironmentEdgeManager.currentTimeMillis();
    return sleepTime;
  }



















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值