HBase篇(6)-HFile合并过程详解

简单地说Compaction 合并是指一个 region 的一个 store 中的一些 HFile 合为一个 HFile 的操作。过程是先从这些待合并的数据文件中读出 KeyValues ,再按照由小到大排列后写入一个新的文件中。之后,这个新生成的文件就会取代之前待合并的所有文件对外提供服务。

HBase 根据合并规模将 Compaction 分为了两类:MinorCompaction 和 MajorCompaction

Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。

Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。

合并storefile的原因

数据加载到memstore,数据越来越多直到memstore占满,再写入硬盘storefile中,每次写入形成一个单独storefile,当storefile达到一定的数量后,就会开始把小storefile合并成大storefile,因为Hadoop不擅长处理小文件,文件越大性能越好。

什么时候合并

触发compaction的方式有三种:Memstore刷盘、后台线程周期性检查、手动触发。

1.Memstore Flush:

应该说compaction操作的源头就来自flush操作,memstore flush会产生HFile文件,文件越来越多就需要compact。因此在每次执行完Flush操作之后,都会对当前Store中的文件数进行判断,一旦文件数大于配置,就会触发compaction。需要说明的是,compaction都是以Store为单位进行的,而在Flush触发条件下,整个Region的所有Store都会执行compact,所以会在短时间内执行多次compaction。

2.后台线程周期性检查:

后台线程定期触发检查是否需要执行compaction,检查周期可配置。线程先检查文件数是否大于配置,一旦大于就会触发compaction。如果不满足,它会接着检查是否满足major compaction条件,简单来说,如果当前store中hfile的最早更新时间早于某个值mcTime,就会触发major compaction(默认7天触发一次,可配置手动触发),HBase预想通过这种机制定期删除过期数据。

3.手动触发:

一般来讲,手动触发compaction通常是为了执行major compaction,一般有这些情况需要手动触发合并

是因为很多业务担心自动major compaction影响读写性能,因此会选择低峰期手动触发;

也有可能是用户在执行完alter操作之后希望立刻生效,执行手动触发major compaction;

是HBase管理员发现硬盘容量不够的情况下手动触发major compaction删除大量过期数据;

如何排序?

由于内存里memstore是在数据插入的过程中就排序的,就是数据插入的时候按照顺序插入,所以memstore里的数据是有序的。当memstore的数据刷写到磁盘时,生成的storefile里的数据也是有序的,这样的话各个storefile里的数据就分别有序了。合并的时候需要将各个有序的storefile合并成一个大的有序的storefile。

首先将各个需要合并的storefile封装成StoreFileScanner最后形成一个List加载到内存,然后再封装成StoreScanner对象,这个对象初始化的时候会对各个StoreFileScanner进行排序放到内部的队列里,排序是按照各个StoreFileScanner最小的rowkey进行排序的。然后通过StoreScanner的next()方法可以拿到各个StoreFileScanner最小rowkey中的最小rowkey对应的KV对。然后就把取出的KV对追加写入合并后的storefile。因为每次取出的都是各个storefile里最小的数据,所以追加写入合并后的storefile里的数据就是按从小到大排序的有序数据。

在合并的过程中会做什么操作?

在合并的过程中会抛弃删除标识的行和版本过旧的行

(1)可以预先定义版本的个数,超过这个值就抛弃

(2)还可以预先定义版本的时间长短,超过这个时间就抛弃,合并完后形成更大的storefile,当达到数量再次合并,直到storefile容量超过一定阀值后会把当前的Region进行分裂为2个并由Hmaster(hbase数据库主控节点)分配到不同的HRegionServer服务器处理实现负载均衡。

如果在合并过程中恰好有涉及到有关storefile的查询发生的话,我们先是把小storefile加载到内存中进行合并此时如有用户访问可以在内存中检索相关数据返回给用户,我们可以想象在内存中做一个独立镜像备份专门提供被查询需求,另一个主体在另一块内存空间里进行合并,当合并完成后释放备份的内存空间,返回到原来的状态。

觉得有价值请关注 ▼

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181205G1P99T00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券