`
半点玻璃心
  • 浏览: 27377 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

HBase Memstore flush代码阅读笔记-2-由单个 memstore大小超过限制触发的 flush

 
阅读更多
本代码基于0.96.1.1:http://svn.apache.org/repos/asf/hbase/tags/0.96.1.1

    默认情况下,当某个 region 的 memstore 大小达到hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier时,会出发 memstore 的 flush 操作,并reject 客户端写请求。
OperationStatus[] batchMutate(Mutation[] mutations, boolean isReplay)
      throws IOException {
    BatchOperationInProgress<Mutation> batchOp =
      new BatchOperationInProgress<Mutation>(mutations);

    boolean initialized = false;

    while (!batchOp.isDone()) {
      if (!isReplay) {
        checkReadOnly();
      }
      checkResources();

      long newSize;
      if (isReplay) {//这里只是做一些简单的工作前置检查,不再码代码了
        startRegionOperation(Operation.REPLAY_BATCH_MUTATE);
      } else {
        startRegionOperation(Operation.BATCH_MUTATE);
      }

      try {
        if (!initialized) {
          if (!isReplay) {
            this.writeRequestsCount.increment();
            doPreMutationHook(batchOp);//检查并调用前置coprocessor
          }
          initialized = true;
        }
        long addedSize = doMiniBatchMutation(batchOp, isReplay);//这里是一个长达300多行的方法。。逼人放弃的节奏啊
        newSize = this.addAndGetGlobalMemstoreSize(addedSize);
      } finally {
        closeRegionOperation();
      }
      if (isFlushSize(newSize)) {
        requestFlush();
      }
    }
    return batchOp.retCodeDetails;
  }

  private void checkResources() throws RegionTooBusyException {
    // If catalog region, do not impose resource constraints or block updates.
    if (this.getRegionInfo().isMetaRegion()) return;
    // 超过设定则请求 flush,并且以异常 reject 写操作。
    if (this.memstoreSize.get() > this.blockingMemStoreSize) {
      requestFlush();
      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);
    }
  }


之所以说是默认情况,是因为建表时指定的flush 大小,优先级高于该设置
  long flushSize = this.htableDescriptor.getMemStoreFlushSize();

    if (flushSize <= 0) {
      flushSize = conf.getLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
        HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE);
    }
    this.memstoreFlushSize = flushSize;
    this.blockingMemStoreSize = this.memstoreFlushSize *
        conf.getLong("hbase.hregion.memstore.block.multiplier", 2);

   其中,某个表的memory store flush size 可以通过在建表或改表如下语句实现:
   htableDescriptor.setMemStoreFlushSize(256 * 1024 * 1024);

   或者 hbase shell:
 
  create|alter 'test', {MEMSTORE_FLUSHSIZE => '268435456'},....
  


接着看“请求 flush 操作”的方法。这里之所以说是请求,是因为该方法只是将region 加入到一个请求列表里面,并未真正的执行了flush,真正的 flush 请求是由其他的线程异步执行的。所以,过多的 flush 任务,会使新的 flush请求阻塞,最终导致整个 RS 都无法响应写请求。
 
 private void requestFlush() {
    if (this.rsServices == null) {
      return;
    }
    synchronized (writestate) {
      if (this.writestate.isFlushRequested()) {
        return;
      }
      writestate.flushRequested = true;
    }
    // Make request outside of synchronize block; HBASE-818.
    this.rsServices.getFlushRequester().requestFlush(this);//如果当前 R 已经在请求队列中,则放弃请求,否则请求 flush
    if (LOG.isDebugEnabled()) {
      LOG.debug("Flush requested on " + this);
    }
  } 

public void requestFlush(HRegion r) {
    synchronized (regionsInQueue) {
      if (!regionsInQueue.containsKey(r)) {
        // This entry has no delay so it will be added at the top of the flush
        // queue.  It'll come out near immediately.
        FlushRegionEntry fqe = new FlushRegionEntry(r);
        this.regionsInQueue.put(r, fqe);
        this.flushQueue.add(fqe);
      }
    }
  }


通过jmap 命令查看,MemStoreFlusher每个 RS 只有一个实例,而 flush 操作的实际执行者为MemStoreFlusher的一个内部类FlushHandler。每个 MemStoreFlusher 默认启用1个 FlushHandler 实例。当然,这个实例可可配置的,通过hbase.hstore.flusher.count 指定.

分享到:
评论

相关推荐

    hbase资料_hbase-default.xml.zip

    5. **文件系统和缓存设置**:`fs.defaultFS`设定默认的HDFS文件系统,`hbase.hregion.blockmultiplier`控制BlockCache的大小,`hbase.hregion.memstore.block.multiplier`则用于控制MemStore的大小。 6. **客户端...

    大数据技术之HBase的面试题.zip

    - 写入时,数据首先被发送到MemStore,当达到一定阈值后,会触发Flush操作,将数据写入HFile。 - 读取时,通过行键定位到对应的Region,然后从HFile和MemStore中查找数据。 5. **HBase的Region分裂**: - 当...

    大数据HBASE考题材料

    - 当MemStore达到一定阈值时,会触发Flush操作,将数据写入StoreFile。 - 随着StoreFile的增多,会触发Compaction操作,将多个StoreFile合并成一个更大的StoreFile,以减少文件的数量并提高查询效率。 - 这个过程...

    hbase性能调优

    - 当StoreFile数量超过该值时,新数据将先进行Split或Compaction,以避免MemStore因等待Flush而导致写入操作被阻塞。 ##### 6. `hbase.regionserver.global.memstore.upperLimit` 和 `hbase.regionserver.global....

    HBase参数修改 PDF 下载

    5. `hbase.hregion.max.filesize`: 单个HRegion的最大大小,超过后会分裂成两个HRegion。 6. `hbase.hregion.memstore.flush.size`: 内存存储单元(MemStore)的刷新阈值,达到该值时会触发数据写入磁盘。 7. `hbase...

    hbase 1.2.0源码

    1. 写操作:客户端将数据写入本地内存,称为MemStore,当达到一定阈值后,会触发一个 flush 操作,将数据写入磁盘形成HFile,同时更新元数据到HMaster。 2. 读操作:通过行键定位到特定的Region服务器,然后在...

    HBase配置文件若干配置.zip

    `hbase.hregion.memstore.flush.size`决定了每个Region内存缓冲区的刷新阈值,当达到此大小时,Region会触发flush操作,将数据写入磁盘。 `hbase.regionserver.handler.count`是RegionServer处理请求的线程数,增加...

    深入学习hbase原理资料整理

    在HBase的生命周期中,当Region的MemStore达到一定大小后,会触发flush操作,此时内存中的数据将被写入HLog,随后形成一个新的HFile存储在HDFS上。这个过程确保了即使在RegionServer宕机的情况下,数据也不会丢失,...

    藏经阁-HBase In-Memory Compaction.pdf

    HBase In-Memory Compaction HBase In-Memory Compaction是HBase存储系统中的一种高性能的存储机制,它基于Log-Structured-Merge(LSM)树设计,通过将数据存储在内存中,减少磁盘I/O操作,提高写入吞吐量和读取...

    Hbase

    1. **Region分裂**:当某个`Region`中的`StoreFiles`大小超过`hbase.hregion.max.filesize`设置值时,该`Region`会被分裂成两个新的`Region`。分裂过程中,新的`Region`指向旧`Region`的`StoreFiles`的不同部分。 2....

    Hbase运维手册.pdf

    当Memstore满64MB时触发flush,当其总大小超过堆内存的特定比例时,会强制flush。 3. **读写请求数**: - 监控各RegionServer的读写请求,分析压力分布,若不均匀可能需要调整Region分布或优化其他系统参数。 4. ...

    HBase文档

    - **hbase.hregion.memstore.flush.size**:设置MemStore刷新到磁盘的阈值大小。 **5.2 性能调优** 为了提高HBase的性能,可以考虑以下方面: - **操作系统层面**:优化操作系统设置,如内存管理、文件系统缓存等...

    携程HBase实践.pdf

    - memStoreSize:RegionServer的memStore大小。 - **新增监控指标**:为了更全面地监控系统性能,还增加了一些新的监控指标,例如GetSize、ScanNextSize、MutateSize、AppendSize、IncrementSize、DeleteSize等,...

    HBase概述——HBase的存储模型.pdf

    此外,当单个Region的大小超过预设阈值时,会发生Region Split。Split期间,Region会暂停服务,直到分裂完成,以保持数据一致性。在多列族场景下,如果数据分布不均,可能会导致不必要的Split操作,引发效率问题。...

    HBase配置项说明及调优建议.zip

    `hbase.hregion.memstore.flush.size`定义了触发MemStore刷新到磁盘的大小。 4. **HDFS相关配置**:HBase依赖于HDFS存储数据。`hbase.fs.defaultFS`指定HDFS的默认文件系统。`dfs.blocksize`设置HDFS的块大小,通常...

    HBase优化-系统架构

    默认设置为3分钟,当超过这个时间,RegionServer将被Zookeeper从RS集群中移除,触发HMaster进行再平衡操作,由其他存活的RegionServer接管。调优时,可以考虑降低这个超时时间以加快failover过程,但过低的设置可能...

    hbase-2.2.2hbase-2.2.2

    写操作首先将数据写入内存的MemStore,当MemStore达到一定大小时,会触发一个 flush 操作,将数据写入磁盘的HFile。 5. **分布式特性**:HBase的分布式特性体现在Region的自动分配和负载均衡上,Master会监控Region...

    某大数据公司内部Hbase性能测试详细设计文档及用例

    在HBase中,数据在更新时首先写入WAL日志(HLog)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的MemStore添加到flush队列,由单独的线程flush到...

    Hbase运维手册范本.doc

    刷新队列是一个重要的性能指标,表示单个 Region 的 Memstore 写满或 RegionServer 上所有 Region 的 Memstore 大小总合达到门限时会进行 Flush 操作。Flush 操作会产生新的 StoreFile,影响 HBase 的读写性能。 ...

Global site tag (gtag.js) - Google Analytics