专栏首页熊训德的专栏Hbase memstore 的刷写时机
原创

Hbase memstore 的刷写时机

HBase会在如下几种情况下触发flush操作,需要注意的是MemStore的最小flush单元是HRegion而不是单个MemStore。可想而知,如果一个HRegion中Memstore过多,每次flush的开销必然会很大,因此我们也建议在进行表设计的时候尽量减少ColumnFamily的个数。hbase官方文档总结的刷写时机有6种:

  1. Memstore级别限制:当Region中任意一个MemStore的大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。
  2. Region级别限制:当Region中所有Memstore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier hbase.hregion.memstore.flush.size,默认 2 128M = 256M),会触发memstore刷新。
  3. Region Server级别限制:当一个Region Server中所有Memstore的大小总和达到了上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 40%的JVM内存使用量),会触发部分Memstore刷新。Flush顺序是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 38%的JVM内存使用量)。
  4. 当一个Region Server中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选取最早的一个 HLog对应的一个或多个Region进行flush
  5. HBase定期刷新Memstore:默认周期为1小时,确保Memstore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行flush导致的问题,定期的flush操作有20000左右的随机延时。
  6. 手动执行flush:用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个Region进行flush。 虽然总的会有6种,细分下flush的时机有三个:一个是单纯的put/delete引起了memstore的变化的,第二个是region的split,merge,compact引起region变化的,第三个是有一个定时线程轮询每一个region是否需要flush(PeriodiaMemStoreFlusher,是一个chore)。

第一个会在hbase的update时候发生,首先会调用checkResources()方法检查资源,这个checkResources()实际上就是检查HRegion的MemStore大小是否超过一定的阈值(hbase.hregion.memstore.flush.size),如果超过,则会调用requestFlush()方法发起对该HRegion的MemStore进行flush的请求,并抛出RegionTooBusyException异常,阻止该操作继续,后续将要讲的Delete、Append等数据更新操作也是如此,在开始执行操作前都会调用这个checkResources()方法来检查资源。而requestFlush方法核心的方法即是调用HRegion的flushcache方法。

第二个是region的splite/merge/compact,在做这些region级别的操作前,都会直接调用flushchache()方法(有关这个方法在上一篇文档中有详细分析),然后再执行操作。这个比较好理解,因为一个region根据CF对应了一系列的Memstore,当region发生变更时所对应的CF的Memstore肯定需要做相应调整,所以要持久化刷硬盘。一般这些过程在hmaster和zk的帮助下都进行的比较快。

第三个是PeriodMemStoreFlusher来定时的刷memstore。

这个定时任务也比较简单,就是定时去检查对应的region以及RegionServer的memstore是否到达了阈值然后去刷写。

需要注意的regionserver的刷写会阻塞整个rs的写,而且这时候很容易发生fullgc,这将很影响整个集群的性能,所以在hbase的文档中也建议,在业务低峰期进行手动刷写,保证不在业务高峰的时候触发memstore刷写条件而影响性能。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hbase Memstore 读写及 flush 源码分析

    本文档主要从源码的角度分析了,hbase 的写缓存的读写以及 flush 过程。因为在分析 wal 的过程中已经把写分析的比较详尽了,本文档概要说明 memst...

    sundyxiong
  • Hbase compaction 源码分析二:详细 compaction 过程

    因为 major compac t很影响 hbase 的读写性能,所以在不同版本是否 major compact 其实社区一直都在寻求优化,可根据需要选择不同的...

    sundyxiong
  • Hbase Replicaition 在腾讯云中应用概述

    Hbase 的 Repliation 是通过 Zookeeper 的协助,从 Master 集群异步往 Slave 集群写 WAL 实现的。可以实现典型的 Ma...

    sundyxiong
  • [每日一题]C语言程序设计教程(第三版)课后习题5.8

    题目描述 企业发放的奖金根据利润提成。利润低于或等于100000元的,奖金可提10%; 利润高于100000元,低于200000元(100000<I≤20000...

    编程范 源代码公司
  • 深入剖析 Android中的 ArrayMap

    数据集合在任何一门编程语言中都是很重要的一部分,在 Android 开发中,我们会实用到ArrayList, LinkedList, HashMap等。其中Ha...

    技术小黑屋
  • Scala基础 - 下划线使用指南

    joymufeng
  • Nodes小程序追加评论功能

    话说,最近深圳发生了一次恶性的超市砍人事件,事发点所在的超市竟然位于花叔第一套房子所在的小区!

    花叔
  • Swift3中的Array内存地址和关联对象的问题

    xferris
  • 6 个新奇的编程方式,改变你对编码的认知

    源 | Reddit 译 | OSC - 周其 我时不时会发现一种编程语言的不同用法它有时候会改变我对编程的看法啊。这篇文章中,我想分享一下让我惊讶的发...

    顶级程序员
  • php将字符串转换为数组实例讲解

    在php中通过使用“explode函数”,将字符串转换为数组,该函数的用法为“explode(delimiter,string)”,其参数delimiter表示...

    砸漏

扫码关注云+社区

领取腾讯云代金券