HBase Memstroe Flush详解

版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/8ff388759c61

关于HBase memstore flush流程之前已有文章介绍,本文主要对触发条件或方式进行展开介绍,便于日后出现问题时追溯原因。

概况来说,memstore flush的情况分为如下6种:

【1、Memstore级别】

Memstore大小达到上限(hbase.hregion.memstore.flush.size,memsotre默认大小128M)时,会触发memstore flush

【2、Region级别】

当一个region中所有memstore大小总和达到了上限(hbase.hregion.memstore.block.multiplier*hbase.hregion.memstore.flush.size,默认2*128M=256M),会触发memstore flush

有一种场景是hbase在写入数据发生阻塞,原因就是这种情况,region server会在写入时检查每个region中的memstore总大小是否超过了单个memstore默认大小的2倍(hbase.hregion.memstore.block.multiplier参数决定),如果超过了则会阻塞写操作,避免产生OOM。由于在flush时还会由compact/split等操作同时进行,因此整个flush过程会比较漫长,必须要等待memstore完全flush到磁盘才会结束,默认regionserver会睡眠hbase.server.thread.wakefrequency(默认10s),再检查memstore大小是不是低于阈值。

生产环境是难以接受10s的等待时间的,因此在无法改变flush过程的时候,可以通过调整如下两个参数来避免或减少region级别的flush。

hbase.hregion.memstore.block.multiplier=10(默认是2,当节点内存充足时可调大此值)

habse.server.thread.wakefrequency=100(默认时10000ms)

【3、Region Server级别】

一个regionserver上会有很多region,意味着大量的memstore,很有可能单个region并没有超过阈值,但regionserver整体的内存占用达到阈值。

当一个region server上所有region中memstore的大小总和达到了head内存的低水位上限(hbase.regionserver.global.memstore.lowerlimit*hbase_heapsize,heap内存的低水位线,默认0.35),会触发部分memstore的flush,flush顺序是按照memstore由大到小执行,先执行memstore最大region的flush操作,再执行次大的,循环执行直到总体memstore内存使用量低于heap*0.35,以降低阻塞全部写操作flush带来的影响;

而当一个region server上所有region中memstore的大小总和达到了heap内存的上限(hbase.regionserver.global.memstore.upperlimit*hbase_heapsize,heap内存的高水位线,默认0.4),会阻塞所有的写操作,将所有memstore都进行flush。

【4、WAL数量达到上限,region级别】

设计这个触发条件的初衷是为了在region server宕掉时,通过WAL恢复的时间不要太久。

WAL的最大值由hbase.regionserver.hlog.blocksize*hbase.regionserver.maxlogs决定。一旦达到这个值,memstroe flush就会被触发。

WAL数量触发的flush策略是找到最早的un-archived WAL文件,将其对应的Region进行flush。

值得一提的是,blocksize (128 mb) * hbase.regionserver.maxlogs大小与hbase.regionserver.global.memstore.upperLimit * HBASE_HEAPSIZE两者之间谁大谁小,个人觉得前者应小于后者,因为若大于后者的话,将会优先做region server级别的flush,阻塞所有写操作,而这个阻塞往往是分钟级别。但cloudera给出的建议是前者大小应略大于后者,以保证不会提前发生flush,这点有待商榷。

【5、定期自动flush】

Region Server在启动时会启动一个线程PeriodicMemStoreFlusher,该线程每隔habse.server.thread.wakefrequency(默认10s)会检查该regeion Server的全部在线Region,当满足以下条件将会触发flush:

memstore中最老记录的时间戳与当前时间的时间间隔超过配置值hbase.regionserver.optionalcacheflushinterval(默认1小时),如果是meta表的region则为5分钟。

如果该参数为0,即为关闭自动刷写。同时,为了避免同时提交的flush太多,会有3~23秒的随机延迟。

【6、数据更新达到阈值】

同样由PeriodicMemStoreFlusher探测,当最后一次flush后的变更次数超过hbase.regionserver.flush.per.changes(默认3千万),也会触发flush。

【7、手工flush】

在hbase shell中调用flush,可以对某张表或某个region进行flush:

flush 'tablename'或flush 'region name'

【X Flush过程】

主要包括三个阶段:

1、prepareFlush阶段

第一步是对memstore做一个snapshot,同时为防止其他线程更新memstore,这里会为加上一个排他锁,阻塞客户端的写操作,由于创建spnashot非常快,因此锁期间对客户影响甚微。

相应打印日志内容为:

……regionserver.HRegion: Started memstore flush for t1,,1413622522846.58fd75078b4a47b8c6a20705f23209b7., current region memstore size 168……

2、flushCache阶段

将上一阶段产生的快照持久化到hdfs上的一个hfile,存放位置为对应reion文件夹下的.tmp目录。

相应打印日志内容为:

……hbase.regionserver.DefaultStoreFlusher: Flushed, sequenceid=562745, memsize=130.9 M, hasBloomFilter=true, into tmp file hdfs://nameservice1/hbase/data/default/f_acct_idtfno_map/1f70d611178c72de82fa5493dbd0772b/.tmp/6e35b0fe71b34f23aa0694a471050f5a

3、commit阶段

将上一阶段产生的临时文件移动到对应的列族目录下,同时删除第一步的snapshot。

相应打印日志内容为:

……regionserver.HStore: Added hdfs://nameservice1/hbase/data/default/data/…

你可能感兴趣的:(HBase Memstroe Flush详解)