HBase的flush和compact
Flush和compact概念Flush触发条件memstore级别限制region级别限制Region Server级别限制HLog数量上限定期Flush Memstore手动Flush
Flush流程Compact合并机制minior compaction(小合并)minior compaction触发条件
major compaction(大合并)major compaction设置自动触发时间major compaction手动触发
Region
Flush和compact概念
flush可以简单的理解为将数据从内存落地到磁盘
每次flush的过程中的prepare阶段都会有短时间的加锁阻塞,这个过程很短不影响读写从region级别的flush触发条件开始,一旦触发,就会flush所有memstore,这是不建议由很多列族的一个重要原因在达到阻塞条件前(默认是JVM内存大小*0.4),可以一边向memstore写数据,一边flush compact可以简单的理解为HFile文件的合并,目的是为了防止小文件过多导致查询效率下降。
Flush触发条件
从容器的大小来看,从小到大可以分为以下3个级别
memstore级别限制
当region中的任意一个 Memstore达到了上限(hbase.hregion.memstore.flush.size,默认128MB),就会触发memstore刷新可以通过更改配置文件来更改默认大小
<property>
<name>hbase
.hregion
.memstore
.flush
.size
</name
>
<value>134217728</value
>
</property
>
region级别限制
当Region中所有Memstore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认 2* 128M = 256M),会触发memstore刷新可以通过更改配置文件来更改默认大小
<property>
<name>hbase
.hregion
.memstore
.flush
.size
</name
>
<value>134217728</value
>
</property
>
<property>
<name>hbase
.hregion
.memstore
.block
.multiplier
</name
>
<value>2</value
>
</property
>
Region Server级别限制
当一个Region Server中所有Memstore的大小总和超过低水位阈值hbase.regionserver.global.memstore.size.lower.limit * hbase.regionserver.global.memstore.size(前者默认值0.95), RegionServer开始强制flush;先Flush Memstore最大的Region,再执行次大的,依次执行;如写入速度大于flush写出的速度,导致总MemStore大小超过高水位阈值hbase.regionserver.global.memstore.size(默认为JVM内存的40% 堆内存),此时RegionServer会阻塞更新并强制执行flush,直到总MemStore大小低于低水位阈值可以通过更改配置文件来更改默认水位大小
<property>
<name>hbase
.regionserver
.global
.memstore
.size
.lower
.limit
</name
>
<value>0.95</value
>
</property
>
<property>
<name>hbase
.regionserver
.global
.memstore
.size
</name
>
<value>0.4</value
>
</property
>
HLogs数量也可以出发flush
HLog数量上限
当一个Region Server钟的HLog数量达到上限时,系统会选取最早的一个HLog对应的一个Region进行flush默认是32个文件,即最大HLog数为32*HDFS的block的大小可通过参数hbase.regionserver.maxlogs配置
在这里插入代码片
从时间上看
定期Flush Memstore
默认周期为1小时,确认memestore不会长时间没有持久化每次flush的操作有20000ms左右的延迟(0~5分钟),避免所有memstore同时刷新,对硬盘造成压力
手动Flush
通过shell命令可以实现手动刷新:
刷新某个表:flush ‘tableName’刷新某个region:flush ‘regionName’
Flush流程
为了减少flush对读写的影响,flush分为三个阶段
prepare阶段:
updateLock加锁阻塞,阻塞所有对region的操作遍历当前region的所有Memstore,将memstore中当前的数据集cellSkipListSet做一个快照snapshot新建一个cellSkipListSet内存块,后续所有的写入操作会写入新的set中释放锁。 (加锁是对memstore和新申请的内存块都加锁,此阶段没有耗时的操作,锁持续时间很短) flush阶段:
遍历所有Memstore,将prepare阶段生成的snapshot持久化为临时文件,存放在目录.tmp下。此阶段涉及磁盘IO操作较为耗时 commit阶段:
将的临时文件移到指定的ColumnFamily目录下,针对HFile生成对应的storefile和Reader,把storefile添加到HStore的storefiles列表中,最后再清空prepare阶段生成的snapshot
补充:ConcurrentSkipListMap(跳跃表)是memstore中应用的数据存储结构,即LSM中内存的实现。 flush过程可能涉及compact和split,太过复杂,在此不叙述
Compact合并机制
Hbase为了防止小文件过多导致查询效率下降,会在必要的时候对夏普的store files进行合并,这个过程称为compation。 compation主要分为两类:
minior compaction(小合并)major compaction(大合并)
compaction触发条件主要分为3类:
每次flush之后,检查HFile总数是否达到小合并条件后台线程周期性检查(2~3小时)
检查周期为hbase.server.thread.wakefrequency * hbase.server.compactchecker.interval.multiplier 手动触发
minior compaction(小合并)
将store中多个HFlie合并成一个HFile,触发比较频繁 小合并的特点:不会删除三类无意义的数据
不会删除超过了TTL(Time to Live)的数据,即过期的数据不会删除超过了版本号的数据不会删除执行了删除操作的数据 以上数据只会被打上墓碑标记,等待大合并的时候删除
minior compaction触发条件
当HFile数目达到一定阈值后会触发小合并**下面配置条件中给出的值都是默认值,如3个文件,最多选取10个文件等
<!--表示至少需要三个满足条件的store file时,minor compaction才会启动
-->
<property>
<name>hbase
.hstore
.compactionThreshold
</name
>
<value>3</value
>
</property
>
<!--表示一次minor compaction中最多选取
10个store file
-->
<property>
<name>hbase
.hstore
.compaction
.max
</name
>
<value>10</value
>
</property
>
<!--默认值为
128m
,
表示文件大小小于该值的store file 一定会加入到minor compaction的store file中
-->
<property>
<name>hbase
.hstore
.compaction
.min
.size
</name
>
<value>134217728</value
>
</property
>
<!--默认值为LONG
.MAX_VALUE,
表示文件大小大于该值的store file 一定会被minor compaction排除
-->
<property>
<name>hbase
.hstore
.compaction
.max
.size
</name
>
<value>9223372036854775807</value
>
</property
>
major compaction(大合并)
合并store中所有的HFile为一个HFile,默认每7天进行一次大合并 大合并的特点:
会从物理上删除超过了TTL的数据、超过了版本号的数据、被删除的数据大合并性能消耗非常大,一般在关闭生产后手动触发
major compaction设置自动触发时间
<!--默认值为
7天进行一次大合并,
-->
<property>
<name>hbase
.hregion
.majorcompaction
</name
>
<value>604800000</value
>
</property
>
major compaction手动触发
major_compact tableName
Region
随着大合并的增多,一个region越来越大,造成数据的存储不平衡,访问速度也会变慢。
所以,当region达到一定大小(默认10G),region会先下线,一分为二,分为两个region,r1,r2. Hmaster会将R2迁移到其他的regionserver中。底层的hfile指向新的region2 最终会更新元数据信息region1 region2到HBASE:meta表