regionserver初始化的时候会初始化两个与compact相关的线程它们分别是:compactionChecker和compactSplitThread。其中compactionChecker用于周期性地检查当前是否有compact请求,实现类是ScheduledChore检查周期由参数threadWakeFrequency控制,默认值是10s,也可以在参数hbase.server.thread.frequency中配置。
另一个成员变量compactSplitThread负责该region server上的compact/split请求具体执行。
其包含了四个线程池分别用于major compact,minor compact split和merge。
compact的大体步骤是:compactionChecker周期性地检查是否有compact请求,如果出现了compact请求,那么将请求以及请求的周边信息一起包装成CompactionContext,将CompactionContext交付给regionserver的compactSplitThread,compactSplitThread会根据compact的类型为它分配合适的线程池,并包装成compactSplitThread内部类CompactionRunner交给对应线程池,线程池调度CompactionRunner,执行它的run方法,完成compact操作。
compactionChecker实现类是CompactionChecker,其继承了ScheduledChore,在之前已经分析过,这个类通过实现chore方法而实现周期性的调用,其初始化是在initializeThreads中:
我们直接看其Chore方法:
这个方法比较简单,取出所有在线的region,遍历region上的所有store(HStore)判断是否需要compact,这里判断是
可以看到最终条件为:HStore中StoreFIles的个数 – 正在执行Compacting的文件个数 > minFilesToCompact。
我们都知道compact分成了两种,monor和major,其区别在官方文档中有说明:
1.Minor操作只用来做部分文件的合并操作以及包括minVersion=0并且设置ttl的过期版本清理,不做任何删除数据、多版本数据的清理工作。也即是说选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。
2.Major操作是对Region下的HStore下的所有StoreFile执行合并操作,最终的结果是整理合并出一个文件。这个过程还会清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。
chore方法中needsCompaction判断的是minor compact是否需要执行。从chore方法中可以直观的看到major compact是通过isMajorCompaction()方法判断的这是很多判断条件的合成,其中最为重要的一个是hbase.hregion.majorcompaction设置的值,也就是判断上次进行majorCompaction到当前的时间间隔,如果超过设置值,则满足一个条件,同时另外一个条件是compactSelection.getFilesToCompact().size() < this.maxFilesToCompact。
因此,通过设置hbase.hregion.majorcompaction = 0可以关闭CompactionChecke触发的major compaction,但是无法关闭用户调用级别的majorcompact。isMajorCompaction,最终实现的判断是来自RatioBasedCompactionPolicyd的isMajorCompaction方法:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。