HBase HFile Compact多种合并策略原理剖析及场景建议-OLAP商业环境实战

本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。版权声明:禁止转载,欢迎学习。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。

网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢!版权声明:禁止转载,欢迎学习

1 HFile合并(寻址风波 => 万物归一)

  • HFile毕竟存储在硬盘上,那么涉及到读操作就涉及:寻址。当HFile文件一多,那么每次读取数据的时候寻址的动作就多了,效率就降低了。
  • 为了减少寻址,减少碎片文件,合并是不得已的优化操作。
  • Minor compact :可以用于把多个HFile文件进行合并,同时可以删除TTL过期的数据,但是手动删除数据操作是不能被删除的。为什么这里可以删除TTL过期的数据?因为MemStore在LSM整理时,对于TTL过期只要不写入HFile文件就算是删除了,而对于手动删除数据操作则可能位于不同的HFile文件中,因此做不到删除。
  • Major Compact:是把一个Store中的HFile文件合并为一个HFile文件,而不是把一个Region内的所有HFile文件,因为一个Region可能有多个Column Family对应的Store。

2:Minor compact 策略百花争鸣

2.1 RatioBasedCompactionPolicy合并策略

  • (1) 对同一个Store的文件,从旧到新逐一扫描所有候选文件,满足其中条件之一便停止扫描:

  • (2) 当前文件大小 < 比它更新的所有文件大小总和 * ratio,其中ratio是一个可变的比例,在高峰期时ratio为1.2,非高峰期为5,也就是非高峰期允许compact更大的文件。那什么时候是高峰期,什么时候是非高峰期呢?用户可以配置参数hbase.offpeak.start.hour和hbase.offpeak.end.hour来设置高峰期

  • (3) 当前所剩候选文件数 >= hbase.store.compaction.min(默认为3)

  • (4) 当前所剩候选文件数 <= hbase.store.compaction.max(默认为5)

  • (5) 停止扫描后,待合并文件就选择出来了,即为当前扫描文件+比它新的所有文件进行合并。

上例中:发现序号为4的文件: 21 < (11+11)*1.2=26.4,符合合并条件。

  • 悖论: 虽然大部分情况都是Memstore快满了的时候才刷写,但是实际情况很复杂,会出现Memstore刷写出来的HFile不一定每次都是一样大。最简单能想到的是:要关闭某一个Region了,Memstore就不得不刷写。因此出现如下情况:

  • 结论: RatioBasedCompactionPolicy太差劲

    经常引起大面积的合并,比如上例中,因为3太小了,肯定满足当前文件大小 < 比它更新的所有文件大小总和 * ratio,发生大面积合并。注意合并的时候就不能写入数据,经常合并就会引起IO,所以HBase在0.96版本之后就修改了合并算法。

2.2 ExploringCompaction默认算法(0.96版本后)

  • 不再武断的认为某个文件满足【当前文件大小 < 比它更新的所有文件大小总和 * ratio】,就把当前所有文件+比它新的所有文件都合并了,很极端。
  • 根据【该文件<(所有文件大小-该文件大小)*比例因子】公式,该公式不再强调顺序性,而是把所有的文件都遍历一遍,若满足公式就把该文件放进待合并队列组合中。
  • 根据hbase.store.compaction.min和hbase.store.compaction.max两个参数选挑选出多个文件组合。 举例如下:
  • 在得到多个组合后,组合里面选择文件数最多,文件数一样多时进一步选择文件总size最小的,目的在于尽可能多地合并文件并且因compact带来的IO压力越小越好;

   当前参数设置如下:
   hbase.store.compaction.ratio=1.2 默认值
   hbase.store.compaction.min=3 默认值
   hbase.store.compaction.max=4 默认值为5
   minCompactSize = 10
复制代码

那么根据需要开始选择多个组合:

  • 如序列1: 根据计算公式:99>((3+12+33+10+11)*1.2),直接排除掉99,因为文件太大了。

  • 其他的文件均满足公式【该文件<(所有文件大小-该文件大小)*比例因子】。因此会有如下组合:

     a: 2 3 4
     b: 2 3 4 5
     c: 3 4 5
     d: 3 4 5 6
     e: 4 5 6
    复制代码
  • 最终选择文件数最多的,同时在b和d中选择文件大小最小的,其中b是58,d是66。因此最终会把b给合并了。

  • Ratio策略是0.94版本的默认策略,而0.96版本之后默认策略就换为了Exploring策略,在cloudera博文《what-are-hbase-compactions》中,作者给出了一个两者的简单性能对比,基本可以看出后者在节省IO方面会有10%左右的提升:

2.3 FIFOCompationPolicy策略(删除策略)

适用场景:

  • 场景在TTL特别短,比如存储一些业务中间表,Mapreduce计算过程中暂时存取数据,用完这些数据就没有用了,该场景下很容易出现整个块的每一个单元格都过期了,
  • BlockCache够大,可以把整个RegionServer上存储的数据都放进去,因此没有必要合并任何文件,因为基本可以走缓存即可。
  • 因为MemStore在LSM整理时,对于TTL过期只要不写入HFile文件就算是删除了,所以FIFOCompationPolicy策略在合并时直接删除所有单元格都过期的块(不落盘而已),可以看到过期的块被整个删除掉了,没有过期的块完全没有操作。整体上只有删除没有复制和移动,优点就是对CPU/IO几乎没有压力。

不适用场景:

  • 表没有设置TTL,或者TTL=FOREVER
  • 表设置了MIN_VERSIONs,并且MIN_VERSIONs>0

悖论:

  • 手工是可以删除MIN_VERSIONs的,会写上墓碑标记,Major Compaction会删除掉带有墓碑标记的。

2.4 DateTieredCompactionPolicy策略(朋友圈原理)

  • 新的1.3版本HBase增加了基于时间戳的分层compact策略,该方法借鉴自Cassandra。
  • 基本思想就是将数据按时间戳分区,使得新老数据在不同的分区,compact行为在不同的分区内发生,这样相当于把compact也按时间戳进行了拆分,好处之一就是提高了按时间读取数据时候的效率,因为从指定的时间分区就可以获取数据,而不再需要遍历所有的文件进行查找。
  • 防止旧文件和新文件合并在一起,因为新文件往往是热点数据。
  • 这里的时间窗不同传统意义上随时间向前滑动的时间窗,而是定期产生的新的时间窗,当前时刻的数据总是写入最新形成的时间窗内。

朋友圈场景,Hbase应该具备什么条件:

  • 为了读取性能,HFile文件必须合并,但是合并的时候必须把新旧文件分开处理,新的和新的合并,旧的和旧的合并。
  • 太早的文件就不再合并了,因为没有人读取,合并旧浪费了磁盘的性能。

DateTieredCompactionPolicy策略参数设置:

  • hbase.hstore.compaction.date.tired.base.window.millis:基本的时间窗口,默认是6个小时,也就是说:从现在到6小时之内的HFile都在同一个时间窗口里面,即这些文件都在最新的时间窗口里面。
  • hbase.hstore.compaction.date.tired.windows.per.tier:层次增长倍数,分层的时候越老的时间窗口越宽。若基本时间窗口为1,则边界一次是3,5,7,15,依次类推。
  • hbase.hstore.compaction.min:在同一个窗口里面文件如果达到最小合并数,文件就会合并,合并策略也是使用ExploringCompaction Policy,所谓策略套策略,太有才了!
  • hbase.hstore.compaction.date.tired.max.tier.age.millis:最老的层次时间。当文件太老了,老到超过所定义的时间范围(以天为单位)就直接不合并了。但是也会存在问题:在这个最老的HFile文件没有TTL过期,当用户手动删除该文件时,因为不会发生Major Compaction,所以这个数据根本就不会真正的删除,而是一直占着磁盘空间。
  • 案例中发现:超过3小于7时,文件合并了。

适用场景:

  • 经常专注于读写最近数据的系统,或者说这个系统专注于最新的数据。
  • 因为该策略有可能引发不了Major Compaction,没有Major Compaction是没有办法删除掉用户手动删除的信息,所以更适用于那些基本不删除数据的系统。
  • 数据根据时间排序存储。
  • 数据只修改最近的数据,基本不删除数据。

不适用场景:

  • 数据改动非常频繁,就连最老的数据也会频繁改动。
  • 经常边读边写数据。

2.5 StripeCompactionPolicy策略(文件分层合并,稳定第一)

  • 分层compact中将所有的文件分成多个层,最顶层的叫L0,其下分别是L1、L2依此类推,同一层内各个数据文件覆盖的rowkey区间不会重叠,相邻层之间的数据文件可以进行compaction,由于区间不重叠每个key处于哪个数据文件是确定的,因此compact过程中,只需部分文件参与即可,而不需要所有文件参与,有助于提高compaction执行效率。新写入的数据会首先落到L0层,从L0层向下依次执行合并。

  • stripe compaction方案借鉴了上述方法,但是只有两层,level 0和level 1,随着数据的写入,memstore flush形成的hfile会首先落到level 0层,一旦level 0层的文件数量超过了用户的设置值,则将这些文件写入到level 1层,level 1层的数据按照rowkey覆盖的范围划分成多个互不重叠的区间,每个区间称为stripe,level 0的数据写入时会首先读出hfile的KVs,然后根据key定位到具体的stripe并将数据插入。

  • 由于level的存在,get数据时会从依据block cache、memstore、level 0和level 1下hfile文件的顺序依次寻找,而compact会细化为level 0中的数据上升到level 1的过程以及level 1层内部数据文件的合并,具体的compact策略复用了前面的exploring方法。每一个stripe相当于划分出的subregion,这样的设计使得compact的粒度变细(从region细化到sub-region级别),冷热数据的compact相隔离,避免了compact时一次扫描整个region下所有的hfile文件进行合并,提高了执行合并的效率,同时减少因compact带来的阻塞时间。

  • a-f 属于一个Strip,g-m 属于一个Strip,以此类推。

StripeCompactionPolicy策略可以解决的问题:

  • 读取链路变长,性能会有损耗,但是提高了查询速度的稳定性。
  • 本来要牵涉全部HFile才能执行Major Compaction,现在可以分Strip执行了,比如:a-f这个strip就可以独立执行Major Compaction 而不牵涉g-m。注意:执行Major Compaction才会真正删除墓碑标记数据,否则数据是删不掉的,这也是我们求贤若渴的原因所在。
  • Major Comapction 一直以来都有牵涉的HFile文件过多造成的IO不稳定的缺点。在StripeCompactionPolicy策略中,一次Major Comapction只会牵涉一个Strip中的所有文件,所以克服了IO不稳定的缺点。

性能测试:

  • 在不同的stripe数量以及不同的L0数量下的读写延迟对比情况,参考对照组可以看出,基本上任何配置下的读响应延迟都有所降低,而写响应延迟却有所升高。

  • 其中两条蓝线分别表示默认情况下的读写延迟曲线,而两条红线表示strips情况下读写延迟曲线,可以明显看出来,无论读还是写,12-stripes配置下的稳定性都明显好于默认配置,不会出现明显的卡顿现象。

场景分析:

stripe compaction也有它特别擅长的业务场景,也有它并不擅长的业务场景。下面是两种stripe compaction比较擅长的业务场景:

  • 大Region。小region没有必要切分为stripes,一旦切分,反而会带来额外的管理开销。一般默认如果region大小小于2G,就不适合使用stripe compaction。
  • RowKey具有统一格式,stripe compaction要求所有数据按照Key进行切分,切分为多个stripe。如果rowkey不具有统一格式的话,无法进行切分,比如:用26个英文字母打头来命名rowkey,就可以保证数据均匀分布。如果使用timestamp来做rowkey,那么数据就没有办法均匀分布了,肯定不适合这个策略。

3 总结(黑猫白猫,抓住老鼠就是好猫)

Compaction对于HBase的读写性能至关重要,掌握好新旧技术的交替,才能让Hbase成为一把利剑。辛苦成文,各自珍惜,谢谢!版权声明:禁止转载,欢迎学习

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HBase是一个开源的分布式数据库,可以在Hadoop集群上运行。以下是HBase的安装和环境配置步骤: 1. 下载HBase:访问HBase官方网站,下载与你的操作系统兼容的最新版本的HBase。 2. 解压文件:将下载的压缩包解压到你选择的目录中。 3. 配置环境变量:打开终端,编辑你的 `~/.bashrc` 或 `~/.bash_profile` 文件(根据你使用的shell),并添加以下行: ``` export HBASE_HOME=/path/to/hbase export PATH=$PATH:$HBASE_HOME/bin ``` 替换 `/path/to/hbase` 为你HBase所在的路径。 4. 配置HBase:进入HBase的安装目录,编辑 `conf/hbase-site.xml` 文件,设置以下属性: ``` <configuration> <property> <name>hbase.rootdir</name> <value>file:///path/to/hbase/data</value> </property> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/path/to/hbase/zookeeper</value> </property> </configuration> ``` 将 `/path/to/hbase/data` 替换为存储HBase数据的目录,将 `/path/to/hbase/zookeeper` 替换为存储ZooKeeper数据的目录。 5. 启动HBase:在终端中运行以下命令启动HBase: ``` $ start-hbase.sh ``` 如果一切正常,你将能够看到HBase启动的日志信息。 6. 验证安装:运行以下命令验证HBase是否正确安装并运行: ``` $ hbase shell ``` 这将打开HBase Shell,你可以在其中执行HBase命令。 以上是HBase的基本安装和环境配置步骤。你可以根据需要进一步配置HBase集群、更改其他属性等。详细的配置和使用指南可以在HBase官方文档中找到。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值