LSM compaction 流程

原本想写一下怎么把compaction和AI结合起来,先转个compaction的简要过程吧。git

参考资料:
https://github.com/abbshr/abb...
https://maiyang.me/post/2017-...
http://leonlibraries.github.i...github

对于LevelDb来讲,写入记录操做很简单,删除记录仅仅写入一个删除标记就算完事了,可是读取记录比较复杂,须要在内存以及各个层级文件中依照新鲜程度依次查找,代价很高。为了加快读取速度,levelDb采起了compaction的方式来对已有的记录进行整理压缩,经过这种方式,来删除掉一些再也不有效的KV数据,减少数据规模,减小文件数量等。post

levelDb的compaction机制和过程与Bigtable所讲述的是基本一致的,Bigtable中讲到三种类型的compaction: minor ,major和full。所谓minor Compaction,就是把memtable中的数据导出到SSTable文件中;major compaction就是合并不一样层级的SSTable文件,而full compaction就是将全部SSTable进行合并。

 LevelDb包含其中两种,minor和major。

朗格科技将为你们详细叙述其机理。

先来看看minor Compaction的过程。Minor compaction 的目的是当内存中的memtable大小到了必定值时,将内容保存到磁盘文件中,图8.1是其机理示意图。


 从8.1能够看出,当memtable数量到了必定程度会转换为immutable memtable,此时不能往其中写入记录,只能从中读取KV内容。以前介绍过,immutable memtable实际上是一个多层级队列SkipList,其中的记录是根据key有序排列的。因此这个minor compaction实现起来也很简单,就是按照immutable memtable中记录由小到大遍历,并依次写入一个level 0 的新建SSTable文件中,写完后创建文件的index 数据,这样就完成了一次minor compaction。从图中也能够看出,对于被删除的记录,在minor compaction过程当中并不真正删除这个记录,缘由也很简单,这里只知道要删掉key记录,可是这个KV数据在哪里?那须要复杂的查找,因此在minor compaction的时候并不作删除,只是将这个key做为一个记录写入文件中,至于真正的删除操做,在之后更高层级的compaction中会去作。

 当某个level下的SSTable文件数目超过必定设置值后,levelDb会从这个level的SSTable中选择一个文件(level>0),将其和高一层级的level+1的SSTable文件合并,这就是major compaction。

咱们知道在大于0的层级中,每一个SSTable文件内的Key都是由小到大有序存储的,并且不一样文件之间的key范围(文件内最小key和最大key之间)不会有任何重叠。Level 0的SSTable文件有些特殊,尽管每一个文件也是根据Key由小到大排列,可是由于level 0的文件是经过minor compaction直接生成的,因此任意两个level 0下的两个sstable文件可能再key范围上有重叠。因此在作major compaction的时候,对于大于level 0的层级,选择其中一个文件就行,可是对于level 0来讲,指定某个文件后,本level中极可能有其余SSTable文件的key范围和这个文件有重叠,这种状况下,要找出全部有重叠的文件和level 1的文件进行合并,即level 0在进行文件选择的时候,可能会有多个文件参与major compaction。

levelDb在选定某个level进行compaction后,还要选择是具体哪一个文件要进行compaction,levelDb在这里有个小技巧,就是说轮流来,好比此次是文件A进行compaction,那么下次就是在key range上紧挨着文件A的文件B进行compaction,这样每一个文件都会有机会轮流和高层的level 文件进行合并。code

若是选好了level L的文件A和level L+1层的文件进行合并,那么问题又来了,应该选择level L+1哪些文件进行合并?levelDb选择L+1层中和文件A在key range上有重叠的全部文件来和文件A进行合并。排序

也就是说,选定了level L的文件A,以后在level L+1中找到了全部须要合并的文件B,C,D…..等等。剩下的问题就是具体是如何进行major 合并的?就是说给定了一系列文件,每一个文件内部是key有序的,如何对这些文件进行合并,使得新生成的文件仍然Key有序,同时抛掉哪些再也不有价值的KV数据。

 Major compaction的过程以下:对多个文件采用多路归并排序的方式,依次找出其中最小的Key记录,也就是对多个文件中的全部记录从新进行排序。以后采起必定的标准判断这个Key是否还须要保存,若是判断没有保存价值,那么直接抛掉,若是以为还须要继续保存,那么就将其写入level L+1层中新生成的一个SSTable文件中。就这样对KV数据一一处理,造成了一系列新的L+1层数据文件,以前的L层文件和L+1层参与compaction 的文件数据此时已经没有意义了,因此所有删除。这样就完成了L层和L+1层文件记录的合并过程。

那么在major compaction过程当中,判断一个KV记录是否抛弃的标准是什么呢?其中一个标准是:对于某个key来讲,若是在小于L层中存在这个Key,那么这个KV在major compaction过程当中能够抛掉。由于咱们前面分析过,对于层级低于L的文件中若是存在同一Key的记录,那么说明对于Key来讲,有更新鲜的Value存在,那么过去的Value就等于没有意义了,因此能够删除。
相关文章
相关标签/搜索