HBase底层的IO行为

本文深入探讨了HBase的IO行为,包括Flush的工作原理,详细介绍了各种触发条件,如Memstore大小、Region级别、Region Server级别、WAL数量达到上限等。此外,还讲解了Compaction的触发时机、选择合适HFile合并的策略以及Major和Minor Compaction的参数配置。最后,文章阐述了Region的split工作原理,分析了不同Region Split策略的优缺点。
摘要由CSDN通过智能技术生成

                                       HBase 底层的IO行为

目录

1 、Flush的工作原理

2 、Compaction的原理

3 、Region的split工作原理

4、 WAL的原理  


 

 

1 、Flush的工作原理

Flush的触发条件:

1.(hbase.regionserver.global.memstore.size)默认;堆大小的40%
regionServer的全局memstore的大小,超过该大小会触发flush到磁盘的操作,默认是堆大小的40%,而且regionserver级别的flush会阻塞客户端读写
 
2.(hbase.hregion.memstore.flush.size)默认:128M
单个region里memstore的缓存大小,超过那么整个HRegion就会flush, 
 
3.(hbase.regionserver.optionalcacheflushinterval)默认:1h
内存中的文件在自动刷新之前能够存活的最长时间
 
4.(hbase.regionserver.global.memstore.size.lower.limit)默认:堆大小 * 0.4 * 0.95
有时候集群的“写负载”非常高,写入量一直超过flush的量,这时,我们就希望memstore不要超过一定的安全设置。在这种情况下,写操作就要被阻塞一直到memstore恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 * 0.4 * 0.95,也就是当regionserver级别的flush操作发送后,会阻塞客户端写,一直阻塞到整个regionserver级别的memstore的大小为 堆大小 * 0.4 *0.95为止
 
5.(hbase.hregion.preclose.flush.size)默认为:5M
当一个 region 中的 memstore 的大小大于这个值的时候,我们又触发 了 close.会先运行“pre-flush”操作,清理这个需要关闭的memstore,然后 将这个 region 下线。当一个 region 下线了,我们无法再进行任何写操作。 如果一个 memstore 很大的时候,flush  操作会消耗很多时间。"pre-flush" 操作意味着在 region 下线之前,会先把 memstore 清空。这样在最终执行 close 操作的时候,flush 操作会很快。
 
6.(hbase.hstore.compactionThreshold)默认:超过3个
一个store里面允许存的hfile的个数,超过这个个数会被写到新的一个hfile里面 也即是每个region的每个列族对应的memstore在fulsh为hfile的时候,默认情况下当超过3个hfile的时候就会 对这些文件进行合并重写为一个新文件,设置个数越大可以减少触发合并的时间,但是每次合并的时间就会越长.

Flush 情况分为以下几种:

【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秒的随机延

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值