本文涉及到很多参数,如微信阅读不友好,可访问 https://www.iteblog.com/archives/2497.html (点击下面 阅读原文 即可进入)原文进行阅读。
接触过 HBase 的同学应该对 HBase 写数据的过程比较熟悉(不熟悉也没关系)。HBase 写数据(比如 put、delete)的时候,都是写 WAL(假设 WAL 没有被关闭) ,然后将数据写到一个称为 MemStore 的内存结构里面的,如下图:
如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop
但是,MemStore 毕竟是内存里面的数据结构,写到这里面的数据最终还是需要持久化到磁盘的,生成 HFile。如下图:
如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop
理解 MemStore 的刷写对优化 MemStore 有很重要的意义,大部分人遇到的性能问题都是写操作被阻塞(Block)了,无法写入HBase。本文基于 HBase 2.0.2,并对 MemStore 的 Flush 进行说明,包括哪几种条件会触发 Memstore Flush 及目前常见的刷写策略(FlushPolicy)。
什么时候触发 MemStore Flush
有很多情况会触发 MemStore 的 Flush 操作,所以我们最好需要了解每种情况在什么时候触发 Memstore Flush。总的来说,主要有以下几种情况会触发 Memstore Flush:
Region 中所有 MemStore 占用的内存超过相关阈值
整个 RegionServer 的 MemStore 占用内存总和大于相关阈值
WAL数量大于相关阈值
定期自动刷写
数据更新超过一定阈值
手动触发刷写
下面对这几种刷写进行简要说明。
Region 中所有 MemStore 占用的内存超过相关阈值
当一个 Region 中所有 MemStore 占用的内存(包括 OnHeap + OffHeap)大小超过刷写阈值的时候会触发一次刷写,这个阈值由 hbase.hregion.memstore.flush.size 参数控制,默认为128MB。我们每次调用 put、delete 等操作都会检查的这个条件的。
但是如果我们的数据增加得很快,达到了 hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier 的大小,hbase.hregion.memstore.block.multiplier 默认值为4,也就是128*4=512MB的时候,那么除了触发 MemStore 刷写之外,HBase 还会在刷写的时候同时阻塞所有写入该 Store 的写请求!这时候如果你往对应的 Store 写数据,会出现 RegionTooBusyException 异常。