LevelDB Compaction之我见
在入职新的团队之后,团队中一青年才俊在介绍NAS和KV相关的知识点的时候,着重说了三遍:如果要学习LSM,一定要看看LevelDB,这是最最经典的KV和LSM架构。好奇心的驱使下果断的下载了源码撸了几遍,撸的快有感觉了。所以记录一点自己的认知,算是个人笔记吧。Compaction可以说是现在KV系统中最核心的功能之一,他几乎决定了真个系统我们常说的行不行的能力。Compaction中文准确的说可以翻译成”归并",意识是指将多个文件通过某种策略合并成一个新的文件。那么划重点:1,多个文件;2,某种策略合并成为一个新的文件。那么本文接下来主要围绕这亮点来解锁LevelDB的Compaction,从而对比现在工作中的KV系统的Compaction,加深理解。
在 LevelDB 中 Compaction 从大的类别中分为两种,分别是:
1,MinorCompaction,指的是 immutable memtable持久化为 sst 文件,本质上是修改指针指向而已
2,Major Compaction,指的是 sst 文件之间的 compaction。
而Major Compaction主要有三种分别为:
1,Manual Compaction,是人工触发的Compaction,由外部接口调用产生,例如在ceph调用的Compaction都是Manual Compaction,实际其内部触发调用的接口是:
void DBImpl::CompactRange(const Slice begin, const Slice end)
2, Size Compaction,是根据每个level的总文件大小来触发,注意Size Compation的优先级高于Seek Compaction
3, Seek Compaction,每个文件的 seek miss 次数都有一个阈值,如果超过了这个阈值,那么认为这个文件需要Compact。
Compaction的入口函数:DBImpl::MaybeScheduleCompaction()
首先是多个文件。LevelDB中用Version这个概念来管理当前某个时间点上的系统的文件:比如有哪些SSTable文件,每个SSTable文件的meta信息。Version 相关的类主要是 VersionSet、Version、VersionEdit。其中 Version 表示一个不可变的元信息版本,所有活跃的 Version 都包含在 VersionSet 的双向链表之中。每个 Version 有引用计数,在生命周期结束之后,会将自己从这个双向链表中摘除。

直接上代码来进行讲解:

files_:表示每一个Level(总共7)的所有的SSTable的元数据信息;
file_to_compact_:表示依据当前这个文件被方问的次数来决定某一个文件是不是应该被选出来做下一次的compaction(中文有点绕);
file_to_compact_level_,表示file_to_compact_所在的level
compaction_score_: score < 1 表示没有必要做compaction
compaction_level_:表示要下一次要compact到那个level,有pickuplevel算出来

浙公网安备 33010602011771号