什么是 MemStore Flush 机制
Region 的 写缓存 MemStore 将数据写入到磁盘中并产生 HFile 文件的过程叫做 MemStore Flush 机制
触发 MemStore Flush 机制的情况
客户端手工触发 Flush 机制
执行 Flush 命令将 Table 表写入 HFile 文件中
MemStore 写缓存大小达到 Flush 阀值
HBase 默认配置文件:hbase-common.jar 中 hbase-default.xml
<property>
<name>hbase.hregion.memstore.flush.size</name>
<value>134217728(128M)</value>
<description>
Memstore will be flushed to disk if size of the memstore
exceeds this number of bytes. Value is checked by
a thread that runsevery hbase.server.thread.wakefrequency.
</description>
</property>
当 MemStore 占用的内存大小达到配置值的时候就会触发一次 Flush 刷写,生成一个 HFile 文件
触发 Memstore 阻塞机制
因为 Flush 是定期检查,所以无法及时在数据到达阈值时触发。如果写入数据增长实在太快,在还未到达检查时间之前,数据就达到 hbase.hregion.memstore.flush.size 的好几倍,将触发 Memstore 阻塞机制
阻塞机制的阈值通过以下公式定义:
hbase.hregion.memstore.flush.size(默认128M) X hbase.hregion.memstore.block.multiplier(默认4) = 512M
默认的阻塞机制阈值是 512MB。如果在下一次 Flush 检查到来之前达到了这个阀值,会立即触发一次刷写。但是这次 Flush 不只是这么简单了,HBase 还会在刷写的时候同时阻塞所有写入该 MemStore 的写请求。这是为了应对如果数据再继续急速增长会带来更可怕的灾难性后果而定制的阻塞机制。
整个 RegionServer 的 MemStore 总和达到阀值
如果整个RegionServer的memstore加起来的大小达到刷写阀值的话,也会触发刷写。具体的阀值计算公式是:
globalMemStoreLimitLowMarkPercent X globalMemStoreSize
- globalMemStoreLimitLowMarkPercent:表示全局 MemStore Flush下限。该配置项是一个百分比,所以取值范围在0.0~1.0,默认为0.95
- globalMemStoreSize:全局的 MemStore容量,它的计算方式为:hbase_heapsize(RegionServer占用的堆内存大小)x hbase.regionserver.global.memstore.size,其中hbase.regionserver.global.memstore.size默认值为0.4。
一旦达到以上这个阀值,就会触发一次强制的 Flush 机制
触发 Memstore 阻塞阈值
类似于单个 MemStore 大小达到某个阀值会阻塞写入,全局的 MemStore 的大小达 globalMemStoreSize 也会阻塞写入
WALs 的数量大于 maxLogs
当 WALs 文件的数量大于 maxLogs 的时候,也会触发一次刷写。不过这个时候 WALs 会报警一下,不过不会阻塞写入。maxLogs 的计算公式:
Math.max(32,(regionserverHeapSizememstoreSizeRatio2/logRollSize)
WALs 文件的数量大于这个值后会触发 MemStore 的 Flush 机制,以便创造新的 MemStore 内存空间用来加载 WALs 中的数据,同时HBase 会给出一个 info 级别的日志。
MemStore 达到 Flush 时间间隔
时间间隔的配置项是:hbase.regionserver.optionalcacheflushinterval
MemStore Flush 间隔时间默认值为 3600000(即1个小时)。如果设定为 0,则意味着关闭定时自动刷写。也就是说如果以上的所有条件都没有被触发到的话,MemStore 还是会每隔一个小时刷写一次,并生成一个 HFile 文件