认识leveldb
Level DB是典型的Log-Structured-Merge Tree的实现,它通过延迟写入以及Write Log Ahead技术来加速数据的写入并保障数据的安全。LevelDB的每个数据文件(sstable)中的记录都是按照Key的顺序进行排序的,但是随机写入时,key的到来是无序的,因此难以将记录插入到其排序位置。于是需要它采取一种延迟写入的方式,批量攒集一定量的数据,将它们在内存中排好序,一次性写入到磁盘中。但是这期间一旦系统断电或其他异常,则可能导致数据丢失,因此需要将数据先写入到log的文件中,这样便将随机写转化为追加写入,对于磁盘性能会有很大提升,如果进程发生中断,重启后可以根据log恢复之前写入的数据。
http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html
一 leveldb特点
1 leveldb是一个持久化存储的KV系统,将大部分数据存储在硬盘中
2 leveldb在存储数据是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key比较函数,leveldb会按用户的比较函数依序存储记录
3 leveldb基本操作包括写记录,读记录和删除记录,也支持针对多条操作的原子批量操作
4 leveldb支持快照功能,还支持数据压缩等操作
二 整体构架
1 构成leveldb静态结构包括6个主要部分: 内存中的MemTable和Immutable MemTable以及磁盘上的几种主要文件:Current文件,Mainifest文件,log文件,SSTable文件
2 log文件在系统中的作用用于系统崩溃恢复而不丢失数据,leveldb在写入内存前先将操作记录到log文件中,然后再记入内存中,这样即使系统崩溃,也可以从log文件中恢复内存中的MemTable,不会造成数据丢失
3 Current文件记录当前manifest文件名,因此在leveldb的运行过程中,随着Compaction的进行,SSTable文件会发生变化,会有新的文件产生,老的文件被废弃,Manifest一会跟着反映这种变化,此时往往会新生成Mainfest文件来记载这种变化
4 MemTable插入的数据占用内存到一个界限后,需将内存中的记录导出到外存中,leveldb会生成新的log文件和MemTable,原来MemTable就成为ImmuTable MemTable,新来的数据被记入新的MemTable,后台调度会将ImmuTable MemTable数据导出到磁盘,形成一个新的SSTable文件
5 SSTable就是由内存中数据不段导出并进行Compaction操作后形成的,SSTable的所有文件是一种层级结构,第一层为Level0, 第二层为Level1, SSTable中文件是key有序排列的,小key记录排在大key记录之前. Level0 的SSTable文件 和其他Level文件有特殊性,这个层级内的.sst文件,两个文件可能存在key重复,其他层级内的.sst文件不会出现同一层级内key重复
三 log文件
1 对于一个log文件,会把它切割以32K为单位的物理Block,每次读取的单位以一个Block为基本读取单位,从物理布局上,一个log文件就是由连续的32K大小的Block构成
2 在leveldb内部,会将一个key:value对看做一条记录的数据,另外在这个数据前增加一个记录头,用来记载一些管理信息.
3 记录头包含3个字段:CheckSum 是对类型和数据的效验码,当leveldb读取记录数据时会对数据进行效验,如果发现和存储的CheckSum相同,说明数据完整无破坏;记录长度记载数据的大小,数据则是上面将的key:value数值对,类型字段则指出每条记录的逻辑结构和log文件物理分块结构间的关系,主要类型有四种:FULL/FIRST/MIDDLE/LAST
四 SSTable文件
1 log文件中记录是key无序,.sst文件内部是根据记录key由小到大排列的
2 .sst文件的物理布局是划分为固定大小的存储块,每个Block分为三部分,红色部分是数据存储区,蓝色Type取用于标识数据存储区是否采用数据压缩算法,CRC部分是数据校验码,用于判定数据是否在生成和传输中出错
3 .sst文件的逻辑布局是划分为数据存储区和数据管理区,数据存储区存放实际kv数据,数据管理区提供一些索引指针等管理数据,目的是更快速便捷的查找相应的记录
4 管理数据分为四种类型, MetaBlock,MetaBlock索引,数据索引和一个文件尾部块,数据存储在Block内容区,每个kv记录包含5个字段 key共享长度,key非共享长度,value长度,key非共享内容,value内容
五 MemTable
1 MemTable 允许写入和读取,当MemTable写入的数据占用内存到达指定数量,则自动转换为ImmuTable MemTable,等Dump到磁盘中,系统会自动生成新的MemTable供写操作写入新数据
2 MemTable并不存在真正的删除操作,删除某个key的value在MemTabe内是作为一条记录实施的,但会打上一个key的删除标记,真正的删除操作是lazy的,会在以后的Compaction过程去掉这个kv
3 leveldb的MemTable中kv对是根据key大小有序存储,在系统插入新的kv,leveldb要把这个kv插到合适的位置上以保持这种key有序性.MemTable类只是一个接口类,真正操作SkipList来做
六 写入与删除
1 对于一个插入操作put(kv)来说,完成插入操作包含两个具体步骤,首先将这条KV记录以顺序写的方式追加到log文件末尾,第二个步骤是如果写log成功,那么将这条kv记录插入内存中的MemTable中
2 插入一条新记录,即先查找合适的插入位置,然后修改相应的链接指针将新记录插入即可,删除操作并不真正删除,而是插入key:删除标记
七 读取记录
1 leveldb首先会去查看内存中的MemTable,如果MemTable中包含key及其对应的value,则返回value值即可,如果MemTable没有读到key,则接下来到同样处于内存中的ImmuTable MemTable中去读取,类似,没有读到就到SSTable文件中查找. 首先从level0的文件中查找,其次到level1中查找,如此循环
2 给定一个要查询的key和某个key range包含这个key的SSTable,leveldb 一般先在内存中的Cache中查找包含这个文件的缓存记录,如果包含,则从缓存中读取,如果不包含,则打开SSTable,同时将这个文件的索引部分加载到内存中并放入Cache中.之后leveldb根据索引定位包含这个key的Block,从文件中读出这个Block的内容,根据记录一一比较,如果找到则返回结果,如果没找到,则说明这个level的SSTable文件并不包含这个key,到下一级别SSTable去查找
八 Compaction操作
1 leveldb读取操作在内存和各个层级文件中依照新鲜程序依次查找,leveldb采取compaction方式来对已有的记录进行整理压缩,来删除不再有效的kv数据,减小数据规模,减少文件数量
2 bigtable 三种类型 minor compaction就是把MemTable中的数据导出到SSTable文件中, major compaction就是合并不同层级的SSTable文件, full compaction就是将所有SSTable进行合并
3 minor compaction的目的是当内存中MemTable大小到一定值时,将内容保存到磁盘文件中,当某个leve下SSTable文件超过一定设置值后,leveldb会从这个level的SSTable文件中选择一个文件(level>0),将其和高一层级的level+1的SSTable文件合并,这就是major compaction
4 level0的文件由于通过minor compaction直接生成,所以任意两个level0的SSTable文件可能在key范哦围上有重叠,所以在major compaction时,对于大于level0的层级,选择其中一个文件就行,对于level0来说,指定某个文件后,要找出本层与它重叠的文件和level1的文件就行合并
5 major对多个文件采取多路归并排序方式,依次找出最小的key记录,之后采取一定标准判断这个key是否还需要保存,有保存价值,那将其写入level+1层中新生成一个SSTable文件,这样对kv数据一一处理,形成新的一系列level+1 层文件,之前参与compaction的level层和level+1层文件失去意义,全部删除. 抛弃key记录的标准时小于level层中存在这个key,那么这个kv在major compaction过程就可以被抛弃
九 cache
1 leveldb中引入两个cache:Table Cache和Block Cache
2 Table Cache中,key值时SSTable的文件名称,value部分包含两部分,一部分指向磁盘打开的SSTable文件的文件指针,另一个指向内存中这个SSTable文件对应的Table结构指针,Table结构保存SSTable的index内容以及用来指示Block Cache用的cache_id,还有其他一些内容
3 Block Cache中,key是文件的cache_id加上这个block在文件中的起始位置block_offset,而value则是这个Block内容
十 版本文件
1 version保存当前磁盘以及内存中所有文件信息,当一次compaction结束后,leveldb会创建一个新的版本作为当前版本,原先的当前版本就会变为历史版本
2 Version set是所有version的集合,管理着所有存活的version
3 VersionEdit 表示version间的变化,相当于delta增量,VersionEdit会保存到mainfest文件中,当作数据恢复时就会从mainfest文件中读出来重建数据
4 当一个Iterator创建以后,Iterator就引用一个当前版本,只要这个Iterator不被delete那个被Iterator引用的版本就一直存活,这意味你用完一个Iterator后,需及时删除它
浙公网安备 33010602011771号