主要基于0.94.17
一 、compaction触发点
1.1 memstore flush 完成之后回见检查是不是需要compaction
1.2 基于Chore(子类CompactionChecker)的检查时间, 时间间隔hbase.server.thread.wakefrequency * mutiplier 。
二 、主压缩 和 次压缩的执行条件
2.1 主压缩
2.1.1 时间周期hbase.hregion.majorcompaction
2.1.2 当次压缩选中的压缩文件数量 = 全部数量 则有次压缩升级为主压缩
2.2 次压缩
2..2.1 当前storefile数量 - 正在压缩的文件数量 > hbase.hstore.compaction.min (老版本对应 hbase.hstore.compactionThreshold, 对于min 还有一些情况判断,为了简洁不过多的去详细)
2.2.2 参考下面压缩算法
--------------------------------------------------------------------------------
重要的配置:
[a] hbase.store.compaction.ratio 压缩文件选取算法中的比例
(默认 1.2f).[b] hbase.hstore.compaction.min
进行compaction的最小文件数(default 2).[c] hbase.hstore.compaction.max
(files) 每次minor compaction的最大文件数量 (default 10).[d] hbase.hstore.compaction.min.size
(bytes) 所有小于该大小的文件都被选为压缩候选对象. 默认等于 hbase.hregion.memstore.flush.size
(128 mb).[e] hbase.hstore.compaction.max.size
(.92) (bytes) 任何大于该值得HStoreFile都被忽略 (default Long.MAX_VALUEThe minor compaction StoreFile selection logic is size based, and selects a file for compaction when the file <= sum(smaller_files) *hbase.hstore.compaction.ratio
.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
将所有的storeFile作为候选对象,先判断region是不是可以写,锁定Store的读,如果有正在压缩的storeFile,从候选对象中去除,然后交由CompactSelection进行选取
1、选取
/* normal skew:
*
* older ----> newer
* _
* | | _
* | | | | _
* --|-|- |-|- |-|---_-------_------- minCompactSize
* | | | | | | | | _ | |
* | | | | | | | | | | | |
* | | | | | | | | | | | |
*/
1.1.判断ttl超时将超时的storeFile返回
1.2.没有超时storeFile的情况下,将上图中老文件大于hbase.hstore.compaction.max.size并且不是引用的文件忽略掉。
1.3 判断是不是主压缩,有两个判断条件符合一个即可
一个是用户级别的压缩请求
另一个条件是达到major压缩条件,并且待压缩的文件数量小于hbase.hstore.compaction.max。 major 压缩条件为TODO
1.4如果不是主压缩,而且文件中没有reference
1.5 判断是不是备选压缩文件超过了hbase.hstore.compaction.min
选取符合条件的文件,此处的算法为:
图片引用自http://www.binospace.com/index.php/in-depth-understanding-of-the-hbase-compaction/
上图是一个maxFilesToCompact (hbase.hstore.compaction.max)= 8 的一个示例,窗口内的每一个值为后面7个(或小于7)的size总和。
进行选取的时候先从第一个开始,跟后面的一个的sum比较,也即是跟后面的7个值得总和进行比较,如果大于sum*ratio 则进行压缩,否则一直进行下去直到找到合适的为止,如果找到合适的之后但是发现小于minFilesToCampact 则不进行压缩。
下面是一个引自官方的一个例子(还有其它例子详细参考:https://hbase.apache.org/book/regions.arch.html):
This example mirrors an example from the unit test TestCompactSelection
.
hbase.store.compaction.ratio
= 1.0fhbase.hstore.compaction.min
= 3 (files)hbase.hstore.compaction.max
= 5 (files)hbase.hstore.compaction.min.size
= 10 (bytes)hbase.hstore.compaction.max.size
= 1000 (bytes)The following StoreFiles exist: 100, 50, 23, 12, and 12 bytes apiece (oldest to newest). With the above parameters, the files that would be selected for minor compaction are 23, 12, and 12.
Why?
2、将上面返回的文件,构建compactionRequest,构建之前对选取的文件和总文件数进行比较如果是相同,则主压缩(但是forcemajor = false)
3、最有把要压缩的文件都放到filesCompacting
,请求之前将region id对应的主压缩或次压缩的次数进行记录
public static void preRequest(final CompactionRequest cr){
Long key = Long.valueOf(cr.getHRegion().getRegionId());
ConcurrentHashMap compactions =
cr.isMajor() ? majorCompactions : minorCompactions;
AtomicInteger count = compactions.get(key);
if (count == null) {
compactions.putIfAbsent(key, new AtomicInteger(0));
count = compactions.get(key);
}
count.incrementAndGet();
}
3、根据文件的大小选择使用largeCompaction 还是smallCompaction,判断的依据默认为:
2 * this.minFilesToCompact * this.region.memstoreFlushSize);
4、执行CompactionRequest中的run 方法,交给Hregion的compact 方法,Hregion再获取store调用Hstore的compact。