hbase实践之flush and compaction

本文主要涉及flush流程,探讨flush流程过程当中引入的问题并阐述2种解决策略,最后简要说明Flush执行策略。sql

对于Compaction,本文主要探讨Compaction要解决的本质问题以及由Compaction引入的问题。面对Compaction带来的双刃剑,如何根据本身的业务模型合理的执行Compaciton,不一样的场景能够采用不一样的Compaction策略以及如何选择待合并文件。nosql

Flush

1. Flush流程(HBase 1.*)
MemStore中的数据,达到必定的阈值,被Flush成HDFS中的HFile文件。

2. 由Flush流程而引入的问题

随着Flush次数的不断增多,HFile的文件数量也会不断增多,那这会带来什么影响?性能

image

Hontonworks测试过的随着HFile的数量的不断增多对读取时延带来的影响如上图所示,随着HFile文件增多,读取延时增大。由于查询一条记录须要读取1~N个HFile文件,文件越多,N越大,读取时间开销越大。测试

针对上述问题,能够减小HFile文件的数量减小读取延时,有2种解决思路:插件

  • 经过compation减小HFile
  • 在内存中执行一部分compaction操做,即HBase2.0中的改进。code

    3. Flush流程(HBase 2.0)

    image

MemStore由一个可写的Segment,以及一个或多个不可写的Segments构成。blog

将一部分合并工做上移到内存。减小Hfile生成数量(4次-->1次),减小写的次数。改善IO放大问题。频繁的Compaction对IO资源的抢占,其实也是致使HBase查询时延大毛刺的罪魁祸首之一教程

  • 那为什么不干脆调大MemStore的大小?这里的本质缘由在于,ConcurrentSkipListMap在存储的数据量达到必定大小之后,写入性能将会出现显著的恶化。

在融入了In-Memory Flush and Compaction特性以后,Flush与Compaction的总体流程演变为:图片

image

4. Flush执行策略

一个Region中是否执行Flush,原来的默认行为是经过计算Region中全部Column Family的总体大小,若是超过了一个阈值,则这个Region中全部的Column Family都会被执行Flush。ip

而2.0版本中默认启用的Flush策略为FlushAllLargeStoresPolicy,也就是说,这个策略使得每一次 只Flush超出阈值大小的Column Family,若是都未超出大小,则全部的Column Family都会被Flush。

改动以前,一个Region中全部的Column Family的Flush都是同步的,虽然容易致使大量的小HFile,但也有好处,尤为是对于WAL文件的快速老化,避免致使过多的WAL文件。而若是这些Column Family的Flush不一样步之后,可能会致使过多的WAL文件(过多的WAL文件会触发一些拥有老数据的Column Family执行Flush)。

Compaction

小范围的HFile文件合并,称之为Minor Compaction,一个列族中将全部的HFile文件合并,称之为Major Compaction。

1. HBase Compaction要解决的本质问题是什么?

减小HFile文件数量,减小文件句柄数量,下降读取时延

Major Compaction能够帮助清理集群中再也不须要的数据(过时数据,被标记删除的数据,版本数溢出的数据)

2. Compaction引入的问题

Compaction会致使写入放大

image

如上图所示,第一个HFile通过屡次minor compaction和一次major compaction后,数据被读取和写入屡次。

在Facebook Messages系统中,业务读写比为99:1,而最终反映到磁盘中,读写比却变为了36:64。WAL,HDFS Replication,Compaction以及Caching,共同致使了磁盘写IO的显著放大。

3. 如何合理的执行Compaction?

compaction能够经过减小HFile的数据来下降读取延时,可是compaction次数不能过多,以控制写入放大的影响。

咱们须要在读取延时(多compaction)和写入放大(少compaction)中折衷,调研本身的业务模型,合理执行Compaction

  • 业务模型参考维度:
写入数据类型/单条记录大小(是不是KB甚至小于KB级别的小记录?仍是MB甚至更大的图片/小文件数据?)
业务读写比例
随着时间的不断推移,RowKey的数据分布呈现什么特色?
数据在读写上是否有冷热特色?
是否只读取/改写最近产生的数据?
是否有频繁的更新与删除?
数据是否有TTL限制?
是否有较长时间段的业务高峰期和业务低谷期?

4. 几种Compaction策略

  • Stripe Compaction

将一个Region划分为多个Stripes(能够理解为Sub-Regions),Compaction能够控制在Stripe(Sub-Region)层面发生,而不是整个Region级别,这样能够有效下降Compaction对IO资源的占用。

适合场景:rowkey是按Stripe顺序写入。

  • Date Tiered Compaction
    Date Tiered Compaction在选择文件执行合并的时候,会感知Date信息,使得Compaction时,不须要将新老数据合并在一块儿。

时序数据就是最典型的一个适用场景。

  • MOB Compaction
    如何存储MB级别的Blob(如图片之类的小文件)数据?

将Blob数据与描述Blob的元数据分离存储,Blob元数据采用正常的HBase的数据存储方式,而Blob数据存储在额外的MOB文件中,但在Blob元数据行中,存储了这个MOB文件的路径信息。MOB文件本质仍是一个HFile文件,但这种HFile文件不参与HBase正常的Compaction流程。仅仅合并Blob元数据信息,写IO放大的问题就获得了有效的缓解。

  • Default Compaction

在选择待合并的文件时是在整个Region级别进行选择的

若是上述几种Compaction策略都没法很好的知足业务需求的话,用户还能够自定义Compaction策略,由于HBase已经具有良好的Compaction插件化机制。

5. 如何选择待合并的文件(minor compaction)

若是一次选择了过多的文件: 对于读取时延的影响时间范围可能比较长,但Compaction产生的写IO总量较低。

若是一次选择了较少的文件: 可能致使过于频繁的合并,致使写IO被严重放大。

  • RatioBasedCompactionPolicy
    f[start].size <= ratio * (f[start+1].size + ….. + f[end – 1].size)

image

  • ExploringCompactionPolicy

RatioBasedCompactionPolicy虽然选择出来了一种文件组合,但其实这个文件组合并非最优的,所以它指望在全部的候选组合中,选择一组性价比更高的组合,性价比更高的定义为:文件数相对较多,而总体大小却较小。这样,便可以有效下降HFiles数量,又可能有效控制Compaction所占用的IO总量。
RatioBasedCompactionPolicy仅仅是在自定义的规则之下找到第一个”可行解“便可,而ExploringCompactionPolicy却在尽量的去寻求一种自定义评价标准中的”最优解“。

请必定要结合实际的业务场景,选择合理的Compaction策略,经过不断的测试和观察,选择合理的配置,何谓合理?能够观察以下几点:
1. 写入吞吐量可否知足要求。随着时间的推移,写入吞吐量是否会不断下降?
2. 读取时延可否知足要求。随着时间的推移,读取时延是否出现明显的增大?
3. 观察过程当中,建议不断的统计分析Compaction产生的IO总量,以及随着时间的变化趋势。

参考文献

一条数据的HBase之旅,简明HBase入门教程-Flush与Compaction

相关文章
相关标签/搜索