HBase是基于LSM树存储模型的分布式NoSQL数据库。LSM树对比普遍的B+树来说,能够获得较高随机写性能的同时,也能保持可靠的随机读性能(可参考这里)。在进行读请求的时候,LSM树要把多个子树(类似B+树结构)进行归并查询,对于HBase来说,这些子树就是HFile(还包括内存上的树结构MemStore)。因此归并查询的子树数越少,查询的性能就越高。
Compact的作用
在写请求的这篇文章里,已经介绍过对于每个写请求,都必须写入MemStore以及HLog才算完成事务提交。当MemStore超过阀值的时候,就要flush到HDFS上生成一个HFile。因此随着不断写入,HFile的数量将会越来越多,根据前面所述,HFile数量过多会降低读性能。为了避免对读性能的影响,可以对这些HFile进行compact操作,把多个HFile合并成一个HFile。compact操作需要对HBase的数据进行多次的重新读写,因此这个过程会产生大量的IO。可以看到compact操作的本质就是以IO操作换取后续的读性能的提高。
Compact的流程
HBase的compact是针对HRegion的HStore进行操作的。compact操作分为major和minor两种,major会把HStore所有的HFile都compact为一个HFile,并同时忽略标记为delete的KeyValue(被删除的KeyValue只有在compact过程中才真正被"删除"),可以想象major会产生大量的IO操作,对HBase的读写性能产生影响。minor则只会选择数个HFile文件compact为一个HFile,minor的过程一般较快,而且IO相对较低。在日常任务时间,都会禁止mjaor操作,只在空闲的时段定时执行。
compact入口
可以请求compact的地方有很多,包括在open region、MemStore flush等都会判断是否需要进行compact操作(单个HStore的MemStore flush之后,如果触发compact操作,则会对所属HRegion下的所有HStore分别进行compact)。除此之外,HRegionServer.CompactionChecker负责定期10 * 1000s针对所有HRegion的HStore检测是否需要进行compact操作。
CompactionChecker判断是否需要进行compact操作的条件如下:
1、HStore下还没有进行compact的HFile的总数 >= hbase.hstore.compaction.min(默认为3),则需要进行compact。
2、如果1不成立,则判断是否需要执行major compact。主要是查看一下是否太久没有执行compact操作。具体判断过程:
1)获得compact时间间隔。hbase.hregion.majorcompaction(默认7天)为base基准时间,hbase.hregion.majorcompaction.jitter(默认5.0)为jitter,公式base + jitter - Math.round(2 * jitter * randomNum) 计算出一个会每次自动抖动的数值作为major compact的时间间隔。之所以要一个自动抖动,就是避免在HRegionServer重启的时候大量的major compact出现造成大量的IO。
2)所有HFile最老(时间戳最小)的那个HFile的时间间隔大于这个major compact的时间间隔,则执行major compact。另外如果HRegion只有一个HFile,并且这个HFile的所有KeyValue的时间戳都没有超过TTL,则表示无须进行major compact,会跳过这次major compact。
当1或2成立都会分别对CompactSplitThread发送compact请求,不同的是,1会异步选择需要进行compact的HFile,2则会进行同步选择。
compact请求
CompactSplitThread是HRegionServer内负责专门执行minor compact、major compact、split、merge操作的线程池。其内部对应4个操作有不同的线程池执行对应的请求。把这些耗时较大的操作放到各自的线程池里有助于提高系统整个吞吐量,同时可以避免某个操作阻塞影响其它操作。
对于每个compact请求,CompactionChecker需要区分出major和minor,然后分配到对应的线程池执行。条件是进行compact的文件总大小 > hbase.regionserver.thread.compaction.throttle(默认2*maxFileCompacts*memstoreFlushSize=2*10*128MB),则为major compact,否则为minor compact。
选择compact的文件操作由对应的HStore进行。CompactionChecker的2会同步选择compact文件,这样就可以马上确定是哪个线程池执行具体的compact操作。但1会异步选择compact进行的HFile时,由于不知道文件总大小,HBase会首先在minor compact的线程池进行compact文件选择操作,选择操作后如果判断为需要进行major compact,则会重新把请求发送到major的线程池进行后续的compact操作。
HStore的compact文件选择
compact文件的选择首先要判断是major还是minor,如果是major,则整个HStore的所有HFile都被选中,否则就选择部分文件进行minor compact。考虑到compact操作都会耗费大量的IO,因此minor compact操作的目标就是以最少的IO代价换取最大的读性能提高。目前在新版本里,HStore的compact文件选择策略能够充分考虑了整体情况去选择最佳的方案。整个过程如下:
- 删除无效文件。 把超过TTL的HFile选择为compact文件。把这些文件compact记录写入WAL,通知所有执行读请求的scanner更新,更新HStore的总文件大小等。
- 选择compact文件。
- 根据选择compact文件更新内部数据。
其中选择compact文件过程是主要步骤,具体如下:
- 把当前HStore所有的HFile作为候选compact文件进行排除操作。
- 排除候选HFile中比正在compact的最新文件还要老的文件。判断文件新老是比较HFile里保存的最大SequenceId(在HLog replay的过程可以判断哪些记录已经写入HFile)决定。SequenceId是HRegion把插入的KeyValue记录写入HLog时作为key一部分的单调递增ID,因此SequenceId越大,则记录越新,也就是HFile越新。
- 排除候选HFile中超过hbase.hstore.compaction.max.size(默认Long最大值)以及非Reference文件。如果不是forceMajor则跳过这步。Reference文件是split region产生的临时文件,只是简单的引用文件,一般必须在compact过程中删除。
- 判断是否major compact。满足用户指定的force major,或者太长时间没有进行compact(CompactionChecker的判断2)且候选文件数小于hbase.hstore.compaction.max(默认10),或者有Reference文件,满足上面三个条件之一则是major compact。
- minor compact继续排除操作。 1、排除在metadata里设置不进行minor compact的HFile(bulkLoad的时候设置) 2、applyCompactionPolicy(后面详述) 3、候选文件数小于hbase.hstore.compaction.min(默认3)则排除全部的候选文件
- 排除候选文件数里超过hbase.hstore.compaction.max(默认10)的部分,如果是major compact则跳过这步,注意从最新的HFile开始进行排除,也就是如果有12个候选文件,则排除掉最后2个最新的HFile。
compact的选择过程中,主要是判断major和minor,然后在配置的最大最小相关限制下进行选择。整个步骤的重点在applyCompactionPolicy,用户可以实现自己的选择策略,HBase主要有两个策略RatioBasedCompactionPolicy和ExploringCompactionPolicy。我们首先假设一个现象:当写请求非常多,导致不断生成HFile,但compact的速度远远跟不上HFile生成的速度,这样就会使HFile的数量会越来越多,导致读性能急剧下降。为了避免这种情况,在HFile的数量过多的时候会限制写请求的速度:在每次执行MemStore flush的操作前,如果HStore的HFile数超过hbase.hstore.blockingStoreFiles (默认7),则会阻塞flush操作hbase.hstore.blockingWaitTime时间,在这段时间内,如果compact操作使得HStore文件数下降到回这个值,则停止阻塞。另外阻塞超过时间后,也会恢复执行flush操作。这样做就可以有效地控制大量写请求的速度,但同时这也是影响写请求速度的主要原因之一。
两者实现如下:
- RatioBasedCompactionPolicy。 从最旧文件开始遍历到最新候选文件,找到小于[hbase.hstore.compaction.min.size(默认为memstore的flush大小,128M)和compact文件总大小*ratio 的最大值]的符合条件文件,如果发现不符合则马上停止搜索。ratio是一个可变的比例,可以通过设置高峰期的时间来改变这个比例,在高峰期时ratio为1.2,非高峰期为5,也就是非高峰期允许compact更大的文件(非高峰期可以耗费更大IO)。 目的是尽可能找到小文件进行minor compact。如果判断这个compact操作后文件数仍然过多会阻塞flush操作,则只是简单选择从最老的文件起,候选文件数减去hbase.hstore.compaction.min(默认3)个文件。
- ExploringCompactionPolicy。 从最旧文件开始遍历所有的候选文件,找出符合[compact文件大小 小于 hbase.hstore.compaction.max.size(默认Long最大值)且所有文件的大小都不会超过其它文件大小*ratio]并且效率最高[compact文件数最多或compact大小最小]。ratio是高峰期比例。注意,由于存在限制,因此可能候选文件被排除到为0个,这时如果判断这个compact操作后文件数仍然过多会阻塞flush操作,则会选择hbase.hstore.compaction.min(默认3)个文件起,符合最大(Long最大值)最小compact大小(128MB)的总大小最小的一个子集合。
可见ExploringCompactionPolicy是基于所有候选文件考虑,而RatioBasedCompactionPolicy则是遍历找到就停止。ExploringCompactionPolicy是新版本的策略,旧版本的RatioBasedCompactionPolicy当时只考虑到最大的文件往往是最老的,但对于bulk-loaded的文件等某些情况则会破坏这个规则,RatioBasedCompactionPolicy的算法就不是最优的压缩策略。
完成compact文件选择后,HStore保存这次compact的结果,并返回给CompactSplitThread。
compact的执行
CompactSplitThread接下来会要求HRegion进行compact请求,HRegion会增加compact的计数值表明正在执行的compact操作,这样可以防止compact过程中,HRegion被关闭。然后HRegion调用具体HStore的compact方法执行真正的compact操作。
HStore的compact操作步骤过程,主要就是把这些HFile写成一个HFile。主要过程为:
- 对所有文件创建对应的scanner,Reference有特殊的scanner。scanner的层次可以参考之前的读请求,最终得到的是一个StoreScanner对象,另外如果是major compact,则会指定在scanner的时候忽略Delete的KeyValue。
- 创建一个临时文件,循环调用scanner的next()方法,把获得的有序的KeyValue写入到临时文件中,然后把这些KeyValue最大的SequenceId写入metadata里。
- 把写到临时文件的compact文件移动到HStore对应的存储目录。
- 把compact的结果写入WAL,RS宕机时就可以依据WAL执行删除旧storeFile
- 用新的compact文件更新HStore内部的数据
- 通知执行读请求中的scanners更新读的HFile,删除旧文件(实际上将其归档),重新计算所有HFile总大小
可以看到在整个compact操作里,只有最后完成compact过程才会对读请求有影响。
完成了HStore的compact操作后,HRegion就会减去之前compact的计数值。返回到CompactSplitThread流程,如果hbase.hstore.blockingStoreFiles(默认7)减去当前的HStore的HFile数。如果<0则表示HRegion将会阻塞后续的memstore flush操作,处于stuck状态则继续调用requestSystemCompaction,否则执行requestSplit查看是否需要split。
至此,就完成了HStore的compact操作。
总结
HBase的compact操作能够通过牺牲当前的IO来获得后来的读性能提高,为了能够减轻compact对系统带来的影响,每次的compact操作都应尽可能选择IO最少,且能提升读性能最大(文件数最多),另外对于major compact,最好应该在集群空闲时间手动触发。
相关推荐
`flush_compact.xml`可能是一个自定义的配置文件,用于调整HBase的刷写和合并策略。 最后,`hive-hbase-handler-1.2.1.jar`是Hive与HBase交互的连接器,它使得用户可以在Hive SQL中直接查询HBase表。这个连接器允许...
* 数据分析:HBase可以用于数据分析,满足数据挖掘和机器学习的需求 * 实时数据处理:HBase可以用于实时数据处理,满足流数据处理的需求 HBase表设计 HBase表设计是指设计HBase表的结构和schema,以满足具体的业务...
其列式存储特性使其在处理稀疏数据时效率高,时间序列数据、多维度数据分析等场景也常选用HBase。 四、HBase表设计 表设计是优化HBase性能的关键。合理的表分区和列族设计能显著提升查询速度。预建分区可避免数据...
在本课程中,主要讲述了HBase详细的架构原理及特点、HBase内部各个角色的详细介绍、安装配置、HBase的Shell操作、新旧版本的读写数据详细流程、HBase的API操作、使用MapReduce以及Hive对HBase数据分析、Rowkey设计、...
- **快速分析能力**:支持实时数据分析,无需预处理即可进行查询。 - **强一致性保障**:在分布式环境下确保数据的一致性,满足高可用性需求。 - **灵活的schema**:允许动态调整列族,适应数据模型的变化。 - **列...
- 监控各RegionServer的读写请求,分析压力分布,若不均匀可能需要调整Region分布或优化其他系统参数。 4. **压缩队列**: - Compact操作涉及文件压缩,会影响读写性能。通过CDH图表库可以监控压缩队列的大小,...
5. `hbase-major-compact-htable.hbase`:HBase的重大合并(Major Compaction)是将多个HFile合并成一个,以减少数据文件的数量并优化空间使用。这个脚本可能就是执行这个操作的命令。 6. `README.md`:这是一个...
"major_compact.sh"是一个执行HBase主合并操作的脚本,主合并是HBase中清理和压缩数据文件的过程,有助于优化存储空间和读写性能。 "云梯1 Hadoop集群架构和服务简介.pdf"可能会详细解释Hadoop集群的架构,包括...
./tsdb fsck --full-scan --threads=8 --fix-all --resolve-duplicates --compact ``` #### 二、Grafana安装与配置 **2.1 Grafana简介** Grafana是一款跨平台的开源度量分析和可视化工具,可以连接各种数据源,...
compact命令和major_compact命令分别用于执行局部压缩和全局压缩操作,优化存储空间的利用。 6. 导出表属性到本地文件:使用describeInJson命令可以将当前表的属性导出为本地的JSON格式文件,方便进行进一步的分析...
NoSQL 数据库是一种非关系型数据库,它们与传统的 SQL 数据库相比,提供了更灵活的数据模型、更高的可扩展性和更好的性能,特别适合大数据处理和实时分析。本篇文章将对比几款主流的 NoSQL 数据库,首先关注的是 ...
本篇将深入探讨如何通过不同的监控指标和工具来分析HBase的运行状况。 首先,关注【操作系统】层面的指标,特别是【IO】、【CPU】和【内存】。IO是衡量磁盘读写活动的重要指标,包括网络IO、磁盘IO和HDFS IO。当IO...
在经验分享部分,支付宝分享了一些重要的教训和优化案例,例如优化HBase中的minorcompact算法、客户端查询请求速度和blocksize设计。针对CTU风险数据项目,通过合理设计rowkey和hregion大小,解决高并发写请求的性能...
32. HBase compact:清理过时数据,压缩文件,减少磁盘占用。 33. Scan与get:get获取单行数据,scan用于扫描多行,可设定缓存和批量大小。 34. HBase特点:列族存储、稀疏性、强一致性、水平扩展。 35. Redis...
* 优化数据存储:可以使用 COMPACT 命令来优化数据存储,例如压缩数据、优化数据结构等。 * 优化资源分配:可以使用 SET 命令来优化资源分配,例如调整资源分配的优先级、设置资源限制等。 Impala 是一款功能强大、...
常见的数据库类型有关系型数据库(如MySQL、Oracle)、分布式数据库(如HBase)和实时数据库(如SQL Server Compact Edition),选择哪种类型取决于数据的特性和应用场景。 信息处理技术则是将收集到的大量数据转化...
8. HBase的HMaster:HMaster负责Region的负载均衡、Region分裂以及分裂后的分配,还处理表的生命周期管理和监控。 9. Loader在FusionInsight中的角色:Loader是数据导入导出工具,支持多种数据源,如NoSQL、FTP、...