1,HBase Compaction
HBase是采用LSM-Tree的架构,随着数据不断写,MemStore Flush不断触发,HFile也会随之不断增加。不进行数据合并会增加集群整体负担以及读写的效率问题。HBase Compaction出现的本质就是为了减少HDFS中的HFile文件数量从而降低存储空间,减少文件句柄数,降低NameNode压力和寻址时间,提高读效率。HBase Compaction从执行层面又分为了Major Compaction 和 Minor Compaction。
Major Compaction,理论上会将一个Store里所有的File文件合并成一个大的StoreFile,同时清理当前Store下涉及到的无效数据,比如过期数据、被标记删除的数据、超过Versions设置的数据。但是Major Compaction会对IO资源进行抢占,会造成写放大问题,即使读多写少的集群,在集群底层读写占比上也会出现写占比放大问题。线上集群的一般做法是关闭自动Major Compaction,在业务低估手动触发Major Compaction的执行,并同时设置Major Compaction 执行时集群资源允许的线程数和流量限制。
Minor Compaction,会根据集群配置策略选取少量的StoreFile进行合并,一般线上配置策略也不会超过10个文件。
HBase Compaction Policy上也有比较丰富的支持,如:RationBasedCompactionPolicy、ExploringCompactionPolicy、FIFOCompactionPolicy、StripeCompactionPolicy等等。该篇主要讲述下DateTieredCompactionPolicy,以及结合实际场景进行参数配置推荐。
2,DateTieredCompactionPolicy
首先我们先看下什么是 DateTieredCompaction。官网:Date tiered compaction is a date-aware store file compaction strategy that is beneficial for time-range scans for time-series data。简义:日期分级压缩策略,是一种日期感知的存储文件压缩策略,是一种有利于时间范围性质的时间序列数据的压缩处理。比如具有时序性质、时效性的日志数据、监控数据、传感数据等。其基本思想是将数据按时间戳分区,使得新老数据在不同的分区,Compact也在不同的分区内发生。按时间读取数据时,从指定的时间分区就能读取数据,提高读取数据的效率。图示:
定期产生时间窗口,当前时刻数据总是写入最新形成的时间窗内。HFile Compact时,只会Compact同一时间窗口内的HFile,不会跨时间窗进行HFile合并。而太早的HFile文件不会再执行合并操作。时间窗口时间跨度、增长倍数、Compact文件数量等参数都可以进行配置。
几个相关配置参数:
hbase.hstore.compaction.date.tiered.max.storefile.age.millis
官网:Files with max-timestamp smaller than this will no longer be compacted.Default at Long.MAX_VALUE.
简译:当HFile老到超过所定义的时间范围就不合并了。默认 Long.MAX_VALUE。
hbase.hstore.compaction.date.tiered.base.window.millis
官网:Base window size in milliseconds. Default at 6 hours.
简译:初始化时间窗口,默认6小时。即最新的数据只要在6小时内都会在最新时间窗口内。
hbase.hstore.compaction.date.tiered.windows.per.tier
官网:Number of windows per tier. Default at 4.
简译:层次增长倍数。默认是4倍。
hbase.hstore.compaction.date.tiered.incoming.window.min
官网:Minimal number of files to compact in the incoming window. Set it to expected number of files in the window to avoid wasteful compaction. Default at 6.
简译:即将Compaction的窗口的最小文件数量,即最小合并数量,默认6。
hbase.hstore.compaction.date.tiered.window.policy.class
官网:The policy to select store files within the same time window. It doesn’t apply to the incoming window. Default at exploring compaction. This is to avoid wasteful compaction.
简译:执行合并的时候使用的策略类。默认是使用 ExploringCompactionPolicy。
适用场景:
考虑对有限时间范围的读取使用日期分级压缩,特别是对最近数据的扫描
不适用场景:
随机查询不受近期有限时间范围限制
频繁删除和更新
频繁的乱序数据写入,特别是使用未来时间戳的写入
频繁的批量写入,时间范围严重重叠
3,实践场景分析
3.1,场景数据
日均数据:1.5T,RegionServer数量:8, 每RS加载磁盘容量:6T * 10
3.2,部分配置参数
#Base
hbase_regionserver_heapsize=64GB
hbase.regionserver.global.memstore.size = 0.65
hbase.hregion.memstore.flush.size = 256MB
hbase.hregion.max.filesize = 100GB
#Split
hbase.regionserver.region.split.policy = org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy
#Compaction
hbase.hregion.majorcompaction = 0
hbase.hstore.compaction.throughput.lower.bound = 52428800
hbase.hstore.compaction.throughput.higher.bound = 104857600
hbase.regionserver.thread.compaction.large = 1
hbase.regionserver.thread.compaction.small = 20
hbase.hstore.compaction.max.size = 5368709120
#DateTiered
hbase.hstore.compaction.date.tiered.max.storefile.age.millis = 453600000
hbase.hstore.compaction.date.tiered.base.window.millis = 21600000
hbase.hstore.compaction.date.tiered.windows.per.tier = 4
hbase.hstore.compaction.date.tiered.incoming.window.min = 5
hbase.hstore.compaction.date.tiered.window.policy.class = org.apache.hadoop.hbase.regionserver.compactions.ExploringCompactionPolicy
3.3,DateTiered配置项计算
前提,经验证,在设置DisabledRegionSplitPolicy,hbase.hregion.max.filesize=1G 场景下,即使Region达到15G后,Region不分裂,且读写正常。
为简化下面的述说,对参数进行简述:
hbase.hstore.compaction.date.tiered.max.storefile.age.millis = age.mills
hbase.hstore.compaction.date.tiered.base.window.millis = window.mills
hbase.hstore.compaction.date.tiered.windows.per.tier = per.tier
hbase.hstore.compaction.date.tiered.incoming.window.min = window.min
1),DateTiered 配置说明
初始化时间窗口大小为 6h,窗口倍数为 4,那么窗口大小依次为6h、24h(1d)、96h(4d)、16d......
2),split 配置说明
禁止自动region分裂
3),Region 配置说明
建表时预划分Region数为256,Region 文件上限参数为100,即月表最多可拥有 25600 个文件。
日均数据:1.5T
日均数据1.5T,分到256个Region,每个Region每日数据约6GB,每个Region每小时数据256M,6小时数据1.5G。
月表数据:1.5T * 31 = 46.5T
月均数据46.5T,最大文件数 25600,每个文件 1.86GB,加上前3层时间窗口的文件不是都能达到 1.86Gb
所以 hbase.hstore.compaction.max.size 不小于 2GB。
按照初始化时间窗口6h,窗口倍数为4,窗口大小依次为6h、24h、96h(4d)、16d、64d...
只要计算单Region的文件数即可,前3层时间窗口文件数计算公式 Region日均数据量 * 天数 / 文件大小 + 变量,
公式中除法向上取整,公式中变量包含:短期内flush的文件或者低于最小合并文件数。
按照上述规则进行参数配套计算:
1),age.mills = 126h,window.min = 5,hbase.hstore.compaction.max.size = 2GB
第1层时间窗口文件数约:6 * 0.25 / 2 + 10 = 11,
第2层时间窗口文件数约:6 * 1 / 2 + 4 = 7,
第3层时间窗口文件数约:6 * 4 / 2 + 4 = 16,
月表后面还有6个4d的时间窗口文件数约:16 * 6 = 96,
总文件数约: 11 + 7 + 16 + 96 = 130
注:这里实际应该会略小于这个值,因为第2层开始算的变量值文件数没有计算数据量;window.min 值每减1,总文件数会减8;后面的场景一样。
超过单Region的文件数 100 ,表示还会进行合并,该配置不符合预计。
2),age.mills = 126h,window.min = 5,hbase.hstore.compaction.max.size = 3GB
第1层时间窗口文件数约:6 * 0.25 / 3 + 10 = 11,
第2层时间窗口文件数约:6 * 1 / 3 + 4 = 6,
第3层时间窗口文件数约:6 * 4 / 3 + 4 = 12,
月表后面还有6个4d的时间窗口文件数约:12 * 6 = 72,
总文件数约: 11 + 6 + 12 + 72 = 101
接近 100
3),age.mills = 126h,window.min = 5,hbase.hstore.compaction.max.size = 4GB
第1层时间窗口文件数约:6 * 0.25 / 4 + 10 = 11,
第2层时间窗口文件数约:6 * 1 / 4 + 4 = 6,
第3层时间窗口文件数约:6 * 4 / 4 + 4 = 10,
月表后面还有6个4d的时间窗口文件数约:10 * 6 = 60,
总文件数约: 11 + 6 + 10 + 60 = 87
略小于最大文件值 100
4),age.mills = 126h,window.min = 5,hbase.hstore.compaction.max.size = 5GB
第1层时间窗口文件数约:6 * 0.25 / 5 + 10 = 11,
第2层时间窗口文件数约:6 * 1 / 5 + 4 = 6,
第3层时间窗口文件数约:6 * 4 / 5 + 4 = 9,
月表后面还有6个4d的时间窗口文件数约:9 * 6 = 54,
总文件数约: 11 + 6 + 9 + 54 = 80
小于最大文件值 100
总结:可见第四种参数配置方案比较符合预期。