HBase源码分析之HRegionServer上MemStore的flush处理流程(二)

HBase源码分析HRegionServerMemStoreflush处理流程(一) 在《HBase源码分析之HRegion上MemStore的flsuh流程(一)》、《HBase源码分析之HRegion上MemStore的flsuh流程)》等文中,我们介绍了HRegion上Memstore flush的主体流程和主要细节。但是,HRegion只是HBase表中按照行的方向对一片连续的数据区域的抽象,它并不能对外提供单独的服务,供客户端或者HBase其它实体调用。而HRegion上MemStoreflush还是要通过HRegionServer来对外提供服务的。下面,我们就详细探究下HR 阅读详情

        继上篇文章《HBase源码分析之HRegionServer上MemStore的flush处理流程(一)》遗留的问题之后,本文我们接着研究HRegionServer上MemStore的flush处理流程,重点讲述下如何选择一个HRegion进行flush以缓解MemStore压力,还有HRegion的flush是如何发起的。

        我们先来看下第一个问题:如何选择一个HRegion进行flush以缓解MemStore压力。上文中我们讲到过flush处理线程如果从flushQueue队列中拉取出的一个FlushQueueEntry为为空,或者为WakeupFlushThread,并且通过isAboveLowWaterMark()方法判断全局MemStore的大小高于限制值得低水平线,调用flushOneForGlobalPressure()方法,按照一定策略,flush一个HRegion的MemStore,降低MemStore的大小,预防OOM等异常情况的发生。

        下面,我们重点分析下flushOneForGlobalPressure()方法,代码如下:

/**
   * The memstore across all regions has exceeded the low water mark. Pick
   * one region to flush and flush it synchronously (this is called from the
   * flush thread)
   * 
   * 所有region的memstore已超过最低水平。
   * 选择一个region同步刷新。
   * 被flush线程调用
   * 
   * @return true if successful
   */
  private boolean flushOneForGlobalPressure() {
	  
	// 获取RegionServer上的在线Region,根据Region的memstoreSize大小倒序排列,得到regionsBySize
    SortedMap<Long, HRegion> regionsBySize =
        server.getCopyOfOnlineRegionsSortedBySize();

    // 构造被排除的Region集合excludedRegions
    Set<HRegion> excludedRegions = new HashSet<HRegion>();

    boolean flushedOne = false;// 标志位
    while (!flushedOne) {// 循环一次,没有选中的话,再循环,直到选中或者没有可选的Region
      
      // Find the biggest region that doesn't have too many storefiles
      // (might be null!)
      // 选择一个Memstore最大的并且不含太多storefiles的region作为最有可能被选中的region,即bestFlushableRegion
      HRegion bestFlushableRegion = getBiggestMemstoreRegion(
          regionsBySize, excludedRegions, true);
      
      // Find the biggest region, total, even if it might have too many flushes.
      // 选择一个Memstore最大的region,即便是它包含太多storefiles,作为最终可以被选中的备份方案,即bestAnyRegion
      HRegion bestAnyRegion = getBiggestMemstoreRegion(
          regionsBySize, excludedRegions, false);

      // 在内存上阈值之上但是没有能够flush的region的话,直接返回false
      if (bestAnyRegion == null) {
        LOG.error("Above memory mark but there are no flushable regions!");
        return false;
      }

      HRegion regionToFlush;
      
      // 选择需要flush的region
      // 如果bestAnyRegion的的memstore大小大于bestFlushableRegion的两倍,则选取bestAnyRegion
      if (bestFlushableRegion != null &&
          bestAnyRegion.memstoreSize.get() > 2 * bestFlushableRegion.memstoreSize.get()) {
        // Even if it's not supposed to be flushed, pick a region if it's more than twice
        // as big as the best flushable one - otherwise when we're under pressure we make
        // lots of little flushes and cause lots of compactions, etc, which just makes
        // life worse!
        if (LOG.isDebugEnabled()) {
          LOG.debug("Under global heap pressure: " +
            "Region " + bestAnyRegion.getRegionNameAsString() + " has too many " +
            "store files, but is " +
            StringUtils.humanReadableInt(bestAnyRegion.memstoreSize.get()) +
            " vs best flushable region's " +
            StringUtils.humanReadableInt(bestFlushableRegion.memstoreSize.get()) +
            ". Choosing the bigger.");
        }
        regionToFlush = bestAnyRegion;
      } else {// 否则,优先选取bestFlushableRegion
        if (bestFlushableRegion == null) {
          regionToFlush = bestAnyRegion;
        } else {
          regionToFlush = bestFlushableRegion;
        }
      }

      // 检测状态:被选中Region的memstoreSize必须大于0
      Preconditions.checkState(regionToFlush.memstoreSize.get() > 0);

      LOG.info("Flush of region " + regionToFlush + " due to global heap pressure");
      
      // 调用flushRegion()方法,针对单个Region,进行MemStore的flush
      flushedOne = flushRegion(regionToFlush, true);
      if (!flushedOne) {// flush失败则添加到excludedRegions集合中,避免下次再被选中
        LOG.info("Excluding unflushable region " + regionToFlush +
          " - trying to find a different region to flush.");
        excludedRegions.add(regionToFlush);
      }
    }
    return true;
  }
        我们来总结下这个方法的处理逻辑,如下:

        1、获取RegionServer上的在线Region,根据Region的memstoreSize大小倒序排列,得到regionsBySize;

        2、构造被排除的Region集合excludedRegions;

        3、标志位flushedOne设置为false;

        4、循环,直到标志位flushedOne为true,即存在Region被选中,或者根本没有可选的Region:

              4.1、循环regionsBySize,选择一个Memstore最大的并且不含太多storefiles的region作为最有可能被选中的region,即bestFlushableRegion:

                       4.1.1、如果当前region在excludedRegions列表中,直接跳过;

                       4.1.2、如果当前region的写状态为正在flush,或者当前region的写状态不是写启用,直接跳过;

                       4.1.3、如果需要检查StoreFile数目,且包含太多StoreFiles,也直接跳过;

                       4.1.4、否则返回该region;

               4.2、循环regionsBySize,选择一个Memstore最大的region,即便是它包含太多storefiles,作为最终可以被选中的备份方案,即bestAnyRegion:

                       4.2.1、如果当前region在excludedRegions列表中,直接跳过;

                       4.2.2、如果当前region的写状态为正在flush,或者当前region的写状态不是写启用,直接跳过;

                       4.2.3、否则返回该region;

               4.3、在内存上阈值之上但是没有能够flush的region的话,直接返回false;

               4.4、选择需要flush的region:

                         4.4.1、如果bestAnyRegion的的memstore大小大于bestFlushableRegion的两倍,则选取bestAnyRegion;

                         4.4.2、否则,优先选取bestFlushableRegion;

               4.5、检测状态:被选中Region的memstoreSize必须大于0;

               4.6、调用flushRegion()方法,针对单个Region,进行MemStore的flush;

               4.7、flush失败则添加到excludedRegions集合中,避免下次再被选中。

        以上就是按照一定策略选择一个HRegion进行MemStore的flush以缓解MemStore压力的方法。那么,剩下的flush指定HRegion的问题就同接下来我们将要讲的HRegion的flush是如何发起的一致了。我们先看下带一个参数的flushRegion()方法,代码如下:

/*
   * A flushRegion that checks store file count.  If too many, puts the flush
   * on delay queue to retry later.
   * 
   * 一个待刷新的Region首先会检测store file的数目,如果太多,会把该region的刷新推迟并稍后再试,否则立即刷新。
   * 
   * @param fqe
   * @return true if the region was successfully flushed, false otherwise. If
   * false, there will be accompanying log messages explaining why the region was
   * not flushed.
   */
  private boolean flushRegion(final FlushRegionEntry fqe) {
    HRegion region = fqe.region;
    if (!region.getRegionInfo().isMetaRegion() &&
        isTooManyStoreFiles(region)) {// 如果Region不是MetaRegion且Region上有太多的StoreFiles
      
      if (fqe.isMaximumWait(this.blockingWaitTime)) {
    	// 如果已阻塞指定时间,记录日志并执行刷新
        LOG.info("Waited " + (EnvironmentEdgeManager.currentTime() - fqe.createTime) +
          "ms on a compaction to clean up 'too many store files'; waited " +
          "long enough... proceeding with flush of " +
          region.getRegionNameAsString());
      } else {
        // If this is first time we've been put off, then emit a log message.
    	// 如果是第一次推迟,并对该HRegion请求分裂或系统合并,记录一条日志信息
        if (fqe.getRequeueCount() <= 0) {
          // Note: We don't impose blockingStoreFiles constraint on meta regions
          // 注意:我们不强加blockingstorefiles约束元区域
          LOG.warn("Region " + region.getRegionNameAsString() + " has too many " +
            "store files; delaying flush up to " + this.blockingWaitTime + "ms");
          
          // 对该HRegion先请求分裂Split,分裂不成功的话再请求系统合并SystemCompaction
          if (!this.server.compactSplitThread.requestSplit(region)) {
            try {
              this.server.compactSplitThread.requestSystemCompaction(
                  region, Thread.currentThread().getName());
            } catch (IOException e) {
              LOG.error(
                "Cache flush failed for region " + Bytes.toStringBinary(region.getRegionName()),
                RemoteExceptionHandler.checkIOException(e));
            }
          }
        }

        // Put back on the queue.  Have it come back out of the queue
        // after a delay of this.blockingWaitTime / 100 ms.
        // 再放回队列,等待900ms(参数可配置)后,再从队列中取出来
        this.flushQueue.add(fqe.requeue(this.blockingWaitTime / 100));
        // Tell a lie, it's not flushed but it's ok
        // 佯言,该Region没有被flush,但是应该返回true
        return true;
      }
    }
    
    // 调用两个参数的flushRegion()方法,通知HRegion执行flush
    return flushRegion(region, false);
  }
        这个带一个参数的flushRegion()方法,实际上是在拿到一个待flush的HRegion的封装体FlushRegionEntry类型的fqe后,对其做一些必要的判断,决定是直接进行flush还是推后执行,且在第一次推后前,如果需要,则做分裂或系统合并处理。具体处理逻辑如下:

        1、如果Region不是MetaRegion且Region上有太多的StoreFiles:

              1.1、通过isMaximumWait()判断阻塞时间,已阻塞达到或超过指定时间,记录日志并执行flush,跳到2,结束;

              1.2、如果是第一次推迟,记录一条日志信息,然后对该HRegion先请求分裂Split,分裂不成功的话再请求系统合并SystemCompaction;

              1.3、再将fqe放回到队列flushQueue,增加延迟时间900ms(参数可配置),等到到期后再从队列中取出来进行处理;

              1.4、佯言,该Region被推迟进行flush,结果还不确定,所以应该返回true;

        2、调用两个参数的flushRegion()方法,通知HRegion执行flush。

        如何进行阻塞时间的判断呢?很简单,判断当前时间减去创建时间是否大于指定时间就OK了。代码如下:

/**
     * @param maximumWait
     * @return True if we have been delayed > <code>maximumWait</code> milliseconds.
     */
    public boolean isMaximumWait(final long maximumWait) {
      return (EnvironmentEdgeManager.currentTime() - this.createTime) > maximumWait;
    }

        好了,是时候该分析这个带有两个参数的flushRegion()方法了。先上代码,再做分析:

/*
   * Flush a region.
   * @param region Region to flush.
   * @param emergencyFlush Set if we are being force flushed. If true the region
   * needs to be removed from the flush queue. If false, when we were called
   * from the main flusher run loop and we got the entry to flush by calling
   * poll on the flush queue (which removed it).
   *
   * @return true if the region was successfully flushed, false otherwise. If
   * false, there will be accompanying log messages explaining why the region was
   * not flushed.
   * 
   * 刷新region
   */
  private boolean flushRegion(final HRegion region, final boolean emergencyFlush) {
    long startTime = 0;
    synchronized (this.regionsInQueue) {
      
      // 先从regionsInQueue中移除对应的HRegion信息
      FlushRegionEntry fqe = this.regionsInQueue.remove(region);
      // Use the start time of the FlushRegionEntry if available
      if (fqe != null) {
        // 获取flush的开始时间startTime
    	startTime = fqe.createTime;
      }
      if (fqe != null && emergencyFlush) {
        // Need to remove from region from delay queue.  When NOT an
        // emergencyFlush, then item was removed via a flushQueue.poll.
    	// 需要从flushQueue队列中移除,如果不是紧急刷新,fqe将通过flushQueue.poll被移除
    	// 因为如果是flush线程处理的,run()方法会周期性的从flushQueue队列取feq,并且如果取出的为null或者WakeupFlushThread,
        // 它会在MemStore位于低水平线上时,按照一定策略选择一个HRegion,包装成fqe进行flush,以降低MemStore,避免OOM等风险,
    	// 此时,如果fqe位于flushQueue中,需要被移除,移除的判断就是这个emergencyFlush是否为true,
    	// 因为通过线程在到期的正常情况下进行处理的,会传入false,而为降低风险进行紧急flush的,会传入true,此时就需要从队列中移除,也是为了避免做重复工作
        flushQueue.remove(fqe);
     }
    }
    
    // 获取flush的开始时间startTime
    if (startTime == 0) {
      // Avoid getting the system time unless we don't have a FlushRegionEntry;
      // shame we can't capture the time also spent in the above synchronized
      // block
      startTime = EnvironmentEdgeManager.currentTime();
    }
    
    // 上读锁,意味着与其他拥有读锁的线程不冲突,可以同步进行,而与拥有写锁的线程互斥
    lock.readLock().lock();
    try {
      
      // 通过监听器Listener通知flush请求者flush的type
      notifyFlushRequest(region, emergencyFlush);
      
      // 调用HRegion的flushcache()方法,执行MemStore的flush
      HRegion.FlushResult flushResult = region.flushcache();
      
      // 根据flush的结果,判断下一步该做如何处理
      
      // 判断是否应该进行合并compact
      boolean shouldCompact = flushResult.isCompactionNeeded();
      // We just want to check the size
      
      // 检测是否应该进行分裂split
      boolean shouldSplit = region.checkSplit() != null;
      
      // 必要的情况下,先进行split,再进行system compact
      if (shouldSplit) {
        this.server.compactSplitThread.requestSplit(region);
      } else if (shouldCompact) {
        server.compactSplitThread.requestSystemCompaction(
            region, Thread.currentThread().getName());
      }
      
      // 如果flush成功,获取flush结束时间,计算耗时,记录HRegion上的度量信息
      if (flushResult.isFlushSucceeded()) {
        long endTime = EnvironmentEdgeManager.currentTime();
        server.metricsRegionServer.updateFlushTime(endTime - startTime);
      }
    } catch (DroppedSnapshotException ex) {
      // Cache flush can fail in a few places. If it fails in a critical
      // section, we get a DroppedSnapshotException and a replay of wal
      // is required. Currently the only way to do this is a restart of
      // the server. Abort because hdfs is probably bad (HBASE-644 is a case
      // where hdfs was bad but passed the hdfs check).
      server.abort("Replay of WAL required. Forcing server shutdown", ex);
      return false;
    } catch (IOException ex) {
      LOG.error("Cache flush failed" +
        (region != null ? (" for region " + Bytes.toStringBinary(region.getRegionName())) : ""),
        RemoteExceptionHandler.checkIOException(ex));
      if (!server.checkFileSystem()) {
        return false;
      }
    } finally {
      // 释放读锁
      lock.readLock().unlock();
      
      // 唤醒阻塞的其他线程
      wakeUpIfBlocking();
    }
    return true;
  }
        带有两个参数的flushRegion()方法大体逻辑如下:

        1、首选处理regionsInQueue集合和flushQueue队列:

              1.1、先从regionsInQueue中移除对应的HRegion信息,这个无论是否紧急flush,都是必须要做的;

              1.2、获取flush的开始时间startTime;

              1.3、如果是紧急刷新,需要从flushQueue队列中移除对应的fqe,如果不是紧急刷新,fqe将通过flushQueue.poll被移除;

        2、如果startTime为null,获取flush的开始时间startTime;

        3、上读锁,意味着与其他拥有读锁的线程不冲突,可以同步进行,而与拥有写锁的线程互斥(后期将会写专门的文章分析HBase内部各流程中锁的应用);

        4、通过监听器Listener通知flush请求者flush的type;

        5、调用HRegion的flushcache()方法,执行MemStore的flush,并获得flush结果;

        6、根据flush的结果,判断下一步该做如何处理:

              6.1、根据flush结果判断是否应该进行合并compact,即标志位shouldCompact;

              6.2、调用HRegion的checkSplit()方法检测是否应该进行分裂split,即标志位shouldSplit;

              6.3、通过两个标志位判断,必要的情况下,先进行split,再进行system compact;

        7、如果flush成功,获取flush结束时间,计算耗时,记录HRegion上的度量信息;

        8、最后释放读锁,唤醒阻塞的其他线程。

        这里,先有必要解释下对flushQueue的特殊处理,如果是紧急刷新,需要从flushQueue队列中移除对应的fqe,如果不是紧急刷新,fqe将通过flushQueue.poll被移除。因为如果是flush线程处理的,run()方法会周期性的从flushQueue队列取feq,并且如果取出的为null或者WakeupFlushThread,它会在MemStore位于低水平线上时,按照一定策略选择一个HRegion,包装成fqe进行flush,以降低MemStore,避免OOM等风险,此时,如果fqe位于flushQueue中,需要被移除,移除的判断就是这个emergencyFlush是否为true,因为通过线程在到期的正常情况下进行处理的,会传入false,而为降低风险进行紧急flush的,会传入true,此时就需要从队列中移除,也是为了避免做重复工作。

        通过监听器Listener通知flush请求者flush的type也很简单,也做注释了,不再解释,代码如下:

private void notifyFlushRequest(HRegion region, boolean emergencyFlush) {
    
	// 默认类型为 FlushType.NORMAL
	FlushType type = FlushType.NORMAL;
    
	// 如果是紧急刷新,跟是否在高水位线上来确定type,高水位线上为FlushType.ABOVE_HIGHER_MARK,低水位线上为FlushType.ABOVE_LOWER_MARK
	if (emergencyFlush) {
      type = isAboveHighWaterMark() ? FlushType.ABOVE_HIGHER_MARK : FlushType.ABOVE_LOWER_MARK;
    }
	
	// 针对监听器逐个添加region、type
    for (FlushRequestListener listener : flushRequestListeners) {
      listener.flushRequested(type, region);
    }
  }
        最后再说说这个flush结果FlushResult,它是HRegion中的一个静态内部类,包括一个Result枚举,其中包含的flush结果如下:

        1、FLUSHED_NO_COMPACTION_NEEDED:flush成功,但是不需要执行compact;

        2、FLUSHED_COMPACTION_NEEDED:flush成功,同时需要执行compact;

        3、CANNOT_FLUSH_MEMSTORE_EMPTY:无法进行flush,因为MemStore为空;

        4、CANNOT_FLUSH:无法进行flush。

        判断flush是否成功,则就是看result是否为FLUSHED_NO_COMPACTION_NEEDED或FLUSHED_COMPACTION_NEEDED,判断是否需要进行compact,则就是看result是否为FLUSHED_COMPACTION_NEEDED。相关代码如下:

    /**
     * Convenience method, the equivalent of checking if result is
     * FLUSHED_NO_COMPACTION_NEEDED or FLUSHED_NO_COMPACTION_NEEDED.
     * @return true if the memstores were flushed, else false.
     */
    public boolean isFlushSucceeded() {
      return result == Result.FLUSHED_NO_COMPACTION_NEEDED || result == Result
          .FLUSHED_COMPACTION_NEEDED;
    }

    /**
     * Convenience method, the equivalent of checking if result is FLUSHED_COMPACTION_NEEDED.
     * @return True if the flush requested a compaction, else false (doesn't even mean it flushed).
     */
    public boolean isCompactionNeeded() {
      return result == Result.FLUSHED_COMPACTION_NEEDED;
    }
        至此,HRegionServer上MemStore的flush处理流程全部分析完毕。末尾关于split、compact,后续会有专门的文章进行介绍,敬请关注本人博客,谢谢!









Regionserver频繁挂掉故障处理实践 近期腾讯云的一家大客户频繁出现HBase regionserver 挂掉,影响业务正常使用。通过调整堆栈大小、gc优化、超时时间等都无法解决该问题。经过细致并综合分析hbase regionserver、hbase master以及 zookeeper的日志,发现了问题所在:tickTime设置导致hbase超时时间错误。 一、故障现象 1、 首先regionserver频繁爆出两类错误: wal.FSHLog: Error syncing, request close of WAL: 以及出现错误: r 阅读详情

相关推荐

hbase 12.1 regionserver 宕机报错记录——1

"Append_min" : 0,     "Append_max" : 0,     "Append_mean" : 0.0,     "Append_median" : 0.0,     "Append_75th_percentile" : 0.0,     "Append_90th_percentile" : 0.0,     "Append_95th_percentile" :

qq_23280769的专栏 7030

Hbase源码分析(十MemStoreflush处理(下)2021SC@SDUSC

文章目录前言一.如何选择一个HRegion进行flush以缓解MemStore压力flushOneForGlobalPressure().HRegion的flush是如何发起的flushRegion()总结 前言 接着上文中提到的问题,本文我们研究HRegionServerMemStoreflush处理流程,重点讲述下如何选择一个HRegion进行flush以缓解MemStore压力,还有HRegion的flush是怎样发起的。 一.如何选择一个HRegion进行flush以缓解MemStore.

qq_45856546的博客 455

Hbase MemStore

1.MemStore的好处? 2.MemStore工作过程?  本文为翻译,原英文地址:http://blog.sematext.com/2012/07 ... at-you-should-know/      当regionserver(以下简称RS)收到一个写请求,会将这个请求定位到某个特定的region。每个region存储了一系列的row,每个row

pengweid专栏 804

HBase源码分析MemStoreflush发起时机、判断条件等详情

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

weixin_33974433的博客 596

Hbase源码分析(十)MemStoreflush处理(上)2021SC@SDUSC

文章目录前言正文总结 前言 本文介绍了HRegion上Memstore flush的主体流程和主要细节。但是,HRegion只是HBase表中按照行的方向对一片连续的数据区域的抽象,它并不能对外提供单独的服务,供客户端或者HBase其它实体调用。而HRegion上MemStoreflush还是要通过HRegionServer来对外提供服务的。 正文 在HRegionServer中,有一个叫做cacheFlusher的东东,它是什么呢?我们先看一下它是如何被定义的: // Cache flushin..

qq_45856546的博客 423

HBase源码分析:HTable put过程

HBase版本:0.94.15-cdh4.7.0 在 HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入、删除、查询数据都需要先找到相应的 RegionServer。什么叫相应的RegionServer?就是管理你要操作的那个Region的RegionServer。Client本身并 不知道哪个RegionServer管理哪个Region,那么它是如何找到相应...

weixin_33697898的博客 103

hbase中Put源码分析

1.     Put put = new Put(key);首先会构造put对象,以传入的rowkey,如果未传入时间戳,那么就会默认为null,接下来就会判断是否传入的控制hbase事务的rowlock,如果传入的rowlock不为空,那么就拿到lockId,赋值给当前lockid. 2.  接下来调用put.add(cfbt,columnKey,columnValue);它会先从fa

i am me,haha,么么哒。。。 1328

hbase源码分析(一):客户端数据入库

  Hbase插入数据的过程大致是: 客户端提交请求给region server(这中间会有作一些缓存) region server接收到请求,判断如果是put请求,将其put到memstore 每次memstore的操作,都会检查memstore是否操作一个阈值,如果超过,就开始执行flush(),这个flush其实就是从内存中的KeyValue对持久化到HStore(也就是HFil...

hf200012 241

HBase0.94在flush操作时候的一个漏洞

基于HBase0.94版本,在高并发写操作时,运行时偶尔出现丢失数据的情况,查看了HBase的日志,出现一下信息,WARN org.apache.hadoop.hbase.regionserver.MemStore: Snapshot called again without clearing previous. Doing nothing. Another ongoing flush or di

云计算、分布式架构、K8S、大数据、机器学习、搜索、推荐、广告 2622

HBase

HBase较重要内容

weixin_70577124的博客 538

hadoop hive 常见问题解决持续更新

安装过程中,由于网络终端,导致下面问题: 问题1:安装停止在获取安装锁 /tmp/scm_prepare_node.tYlmPfrT usingSSH_CLIENT to get the SCM hostname: 172.16.77.20 33950 22 opening logging file descriptor 正在启动安装脚本...正在获取安装锁...BEGIN flock 4 这...

weixin_34122604的博客 1281

hbase-----memstore flush 流程代码分析

flush的整体流程分三个阶段   HBase采用了类似于两阶段提交的方式,将整个flush过程分为三个阶段。 1)prepare阶段:遍历当前Region中的所有MemStore,将MemStore中当前数据集CellSkipListSet(内部实现采用ConcurrentSkipListMap)做一个快照snapshot,然后再新建一个CellSkipListSet接收新的数据写入。prepare阶段需要添加updateLock对写请求阻塞,结束之后会释放该锁。因为此阶段没有任何费时操作,因此持锁时

cyq6239075的博客 910

hbase DroppedSnapshotException

hbase夯机问题: FATAL org.apache.hadoop.hbase.regionserver.HRegionServer: ABORTING region server : Replay of WAL required. Forcing server shutdown? Caused by: org.apache.hadoop.hbase.exceptions.TimeoutIO...

奈文摩尔ST 711

RegionServer架构以及HBase读写流程MemStore Flush时机

文章目录RegionServer架构写流程流程MemStore Flush时机1、MemStore级别2、Region级别:当写入速度大于flush速度时(写高峰),可能达到这个值3、RegionServer级别4、Hlog级别5、定期刷写6、手动刷写 RegionServer架构 写流程 Client先访问zookeeper,获取hbase:meta表位于哪个Region Server。 访问对应的Region Server,获取hbase:meta表,根据写请求的namespace:table/

ZYN的博客 1036

hbase中regionserver的flush过程

1、regionServer的全局memstore的大小,超过该大小会触发flush到磁盘的操作,默认是堆大小的40%,  而且regionserver级别的flush会阻塞客户端读写 &lt;property&gt;          &lt;name&gt;hbase.regionserver.global.memstore.size&lt;/name&gt;          &lt;val...

carrialine的博客 1003
上一篇: HBase源码分析之HRegionServer上MemStore的flush处理流程(一)
下一篇: HBase源码分析之MemStore的flush发起时机、判断条件等详情
lipeng_bigdata
博客等级 码龄11年 687粉丝 175原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值