Hbase的flush以及compaction的一些理解

  最近自己看了一些关于flush和compaction的博客,其中也有一些总结和感悟,于是想写下来,以供后续参考,如果有理解的不对的地方,我们可以一起讨论~

什么是Flush和Compaction?它们是在什么情况下进行的呢?他们的作用是什么?

Flush我理解的就是将memstore中缓存的写入数据溢写到hdfs上,之前看博客一直理解它是当memstore中的数据达到一定阈值的时候就触发flush,但是它并不是我想的这么简单(见文章后半部分)。Compaction我理解的就是合并hdfs上多个小的hfile,将其合并成一个大的hfile,减少获取数据时的读取消耗,毕竟文件那么多一个个去找应该是比找一个大的要费时间,而且我认为hdfs上存取多个小的hfile可能有小文件问题?

Compaction分minor Compaction和major Compation,小范围的HFile文件合并,是minor Compaction,一个列族中将所有的HFile文件合并,是major Compaction,并且major Compaction可以删除过期数据,被标记删除的数据,版本数溢出的数据。通俗的说一下,就是minor Compation只是对某一个Region下面的部分hfile进行合并,而major Compaction是对整个region下的hfile进行合并,并且还有清除数据的功能。

Memstore的数据结构  

memstore中的数据结构是CellSet,而CellSet是由ConcurrentSkipListMap实现的(具体见这篇博文:博文),然后更加细致的就是memstore将自己分为一个可写的Segment,以及一个或多个不可写的Segments构成(具体见这篇博文:博文),来的数据先写在Active Segment,然后到达阈值时就flush成一个Immutable Segment,然后后来的数据再往Active Segment里面写,等到immutable Segment越来越多,就会触发Immutable Segment的compation,合并成一个大的immutable Segment,等它达到一定阈值的时候,就持久化成hfile到hdfs上面(这些是我看文章的理解和猜想)。为什么要这么做呢?文章里面解释的是:"如果MemStore中的数据被直接Flush成HFile,而多个HFile又被Compaction合并成了一个大HFile,随着一次次Compaction发生以后,一条数据往往被重写了多次,这带来显著的IO放大问题,另外,频繁的Compaction对IO资源的抢占,其实也是导致HBase查询时延大毛刺的罪魁祸首之一"。

我当时想的是,反正也是在内存里面对immutable Segment要进行合并,持久化成hfile之后在hdfs上到达一定数量也得触发compaction,其实感觉发生compaction的次数应该是差不多的。后来想明白了,应该是在内存里面进行合并比在磁盘上进行合并消耗的资源和IO要少很多,并且速度也相对较快。并且此时的compaction的数据是在内存中,它不像hfile在hdfs上会有副本,这样的话,只需要对一份数据进行compaction就可以了,不需要对三份副本也进行同样的操作。

另外为什么不把memstore设置的大一些呢?也是有原因的,因为它的特定的数据结构决定了当它的容量达到一定大小的时候,memstore的写入性能会受到极大的影响。

到这里,我有一个问题,并且针对这个问题我有个猜想(具体怎么样需要在多看一些博客或者看源码解决):我们知道hbase的数据是按照rowkey排序的,我们写数据的时候是随即写,并且写到的最终目的地是放到了hdfs上,而hdfs不允许修改数据,那么它是怎么有序的呢?我查了一些资料是说在memstore中进行了排序,然后flush到磁盘的时候,此时其中的hfile已经是有序的了,那么当我再对同一个rowkey,同一个列族,同一个列的值进行修改的时候,我肯定是重新先去找这个rowkey在哪个region里面,然后将这条新的记录写到对应region中,最后落地到hfile中,最后交到compaction去做数据合并,将老版本的数据去除,这样就达到了数据更新的目的。

猜你喜欢

转载自blog.csdn.net/a6822342/article/details/82785524