HBase的合并策略有四种
1,RatioBasedCompactionPolicy(以前版本的默认缺省值)
2,ExploringCompactionPolicy(现在版本的默认缺省值)
3,FIFOCompactionPolicy
4,StripeCompactionPolicy
前面有重要的方法:needsCompaction,isMajorCompaction,selectCompaction
RatioBasedCompactionPolicy
needsCompaction
除了正在合并的文件数大于我们系统所配置的最小合并数就返回true就应该合并是miniCompaction
isMajorCompaction
1,首先获取下次Major Compaction的时间,配置的时间间隔是7天,获取配置的抖动系数jitterPct默认缺省值0.5,最后随机得到一个值。
2,获取最老的文件的时间戳
如果该文件已经到了得到的下次Major Compaction时间
获取配置的TTL的值cfTtl
2.1如果要合并的文件只有一个,获取最小时间戳minTimestamp
2.1.1 如果该文件是合并生成的,并且TTL未过期
如果blockLocalityIndex小于comConf.getMinLocalityToForceCompact的配置值,则为true
2.1.2 如果TTL已过期,则问true
2.2,如果合并的文件为多个则为true
总结:如果有多个文件,则问true,如果只有一个,两个原因可以true:本地化,和TTL过期
selectCompaction
1.判断是否需要mayBeStuck, 如果当前store中hfile的数量太多,并且超过了我们设置的参数 默认缺省值为7
2,通过getCurrentEligibleFiles方法选择要文件:把目前正在合并的文件的最后一个在所有storeFile中的位置前(含)的删除,这一步如果没有删除掉文件,则isAllFile为true,否则为fale
3,如果forceMajor为false且isAllFile为true 则调用skipLargeFiles过滤掉超过配置阈值的大文件,如果此时还没删除文件则isAllFile为true否则为false;
4,看是否尝试一下MajorCompaction赋值给isTryingMajor,两个条件满足一个即可:
1)forceMajor && isAllFiles && isUserCompaction
2)(((forceMajor && isAllFiles) || isMajorCompaction(candidateSelection))
&& (candidateSelection.size() < comConf.getMaxFilesToCompact()))
5,判断是否有Reference文件
如果isTryingMajor也没有Reference文件
1)过滤BulkLoad文件
2)调用applyCompactionPolicy方法选择一组候选文件
(1)获取一个配置的比率ratio,两个long数组fileSizes求出每个文件的大小,sumSize求出从自己下标开始算起合并最多文件个数的总大小
(2)循环遍历数组fileSizes,如果该文件大小大于后面文件综合大小的ratio倍,则跳过
start++
3)如果最后start=总候选文件数,且mayBeStuck为true,我们只合并配置的min个最后的文件
4)清空start前的文件
6,清理超过配置的最大合并数的文件
7,此事后还没有删除一个文件则,isAllFile设置为true,否则设置为false
8,组装成一个CompactionRequest对象,设置属性返回该CompactionRequest对象
ExploringCompactionPolicy
ExploringCompactionPolicy是RatioBasedCompactionPolicy的子类
重写了applyCompactionPolicy选文件的方法
实际调用重载方法如下:
跟父类比的不同是,父类找到就结束,子类是依次相比较找到最优解
为了达到少io保持扔掉更多的文件files,或者相同的文件数,选择文件的数目大于原来的数目 或者数目相等但是大小更小
FIFOCompactionPolicy
FIFOCompactionPolicy是ExploringCompactionPolicy的子类
重写覆盖了一下方法:selectCompaction,,isMajorCompaction,needsCompaction
selectCompaction
1,forceMajor不能用于FIFOCompactionPolicy
2,如果有Reference文件则调用父类的方法
否则返回TTL过期的文件形成CompactionRequest对象返回
isMajorCompaction
如果有Reference文件则调用父类的同名方法
否则返回false
needsCompaction
如果有Reference文件则调用父类的同名方法
否则只要有TTL的过期文件则返回true
StripeCompactionPolicy
StripeCompactionPolicy是CompactionPolicy的子类有一个ExploringCompactionPolicy属性,可以看做是一个修饰者模式(包装类)。
StripeCompaction会将整个store中的文件按照Key划分为多个Range,在这里称为stripe,stripe的数量可以通过参数设定,相邻的stripe之间key不会重合。实际上在概念上来看这个stripe类似于sub-region的概念,即将一个大region切分成了很多小的sub-region。
随着数据写入,memstore执行flush之后形成hfile,这些hfile并不会马上写入对应的stripe,而是放到一个称为L0的地方,用户可以配置L0可以放置hfile的数量。一旦L0放置的文件数超过设定值,系统就会将这些hfile写入对应的stripe:首先读出hfile的KVs,再根据KV的key定位到具体的stripe,将该KV插入对应stripe的文件中即可,之前说过stripe就是一个个小的region,所以在stripe内部,依然会像正常region一样执行minor compaction和major compaction,可以预想到,stripe内部的majorcompaction并不会太多消耗系统资源。另外,数据读取也很简单,系统可以根据对应的Key查找到对应的stripe,然后在stripe内部执行查找,因为stripe内数据量相对很小,所以也会一定程度上提升数据查找性能。
重写覆盖了如下方法selectCompaction,needsCompactions,isMajorCompaction,throttleCompaction
直接返回false一个
l0达到配置的最小值即可