HBase MemStore 的刷写时机
Flush 时机
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,默认 4 * 128M = 512M),会触发 MemStore 刷新。
3. Region Server 级别限制
当 RegionServer 中 MemStore 的大小总和超过低水位阈值hbase.regionserver.global.memstore.size.lower.limit
* hbase.regionserver.global.memstore.size
,RegionServer开始强制执行 flush,先 flush MemStore 最大的Region,再 flush 次大的,依次执行。
如果此时写入吞吐量依然很高,导致总 MemStore 大小超过高水位阈值hbase.regionserver.global.memstore.size
,RegionServer 会阻塞更新并强制执行 flush,直至总 MemStore 大小下降到低水位阈值。
参数 | 默认值 |
---|---|
hbase.regionserver.global.memstore.size | 0.4 |
hbase.regionserver.global.memstore.size.lower.limit | 0.95 |
如果有 16G 堆内存,默认情况下:
1 | # 达到该值会触发刷写 |
相信好多人会在网上看到 hbase.regionserver.global.memstore.upperLimit、hbase.regionserver.global.memstore.lowerLimit 这两个参数。
这两个参数已经发生了改变了。对应的新参数如下:
新参数 | 老参数 |
---|---|
hbase.regionserver.global.memstore.size | hbase.regionserver.global.memstore.upperLimit |
hbase.regionserver.global.memstore.size.lower.limit | hbase.regionserver.global.memstore.lowerLimit |
的确,当时我也看了老版本的 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内存使用量)。
按照老版本来看,我发现新搭建的集群配置怎么不对,lowerLimit 怎么比 upperLimit 还高。一度让我弄混。
直到我弄清楚 hbase.regionserver.global.memstore.size.lower.limit 是分配给 MemStore 最大内存的刷新的低水位线才明白。
大家可以参阅官方文档对两个新参数的解释。
4. HLog 数量限制
当一个 Region Server 中 HLog 数量达到上限(可通过参数 hbase.regionserver.maxlogs 配置)时,系统会选取最早的一个 HLog 对应的一个或多个 Region 进行 flush
5. 定期刷新
HBase 定期刷新 MemStore (hbase.regionserver.optionalcacheflushinterval), 默认周期为1小时,确保 MemStore 不会长时间没有持久化。为避免所有的 MemStore 在同一时间都进行 flush 导致的问题,定期的 flush 操作有 20000 左右的随机延时。
hbase.regionserver.optionalcacheflushinterval 参数设置为 0 可关闭。CDH 管理页面上没有直接设置
6. 手动执行
可以通过 shell 命令 flush ‘tableName’ 或者 flush ‘regionName’ 分别对一个表或者一个 Region 进行 flush。
7. 其他
执行 Compact 和 Split 之前,会进行一次 flush
参考链接