三、levelDB整体框架之sstable,manfest文件,current文件

二、levelDB整体框架,及memtable、log文件、immutable memtable  
之中已经讲了leveldb的三个组件,其中log文件和加下来的sstable文件是学习leveldb的重点内容,并且sstable比log文件相对复杂一些。
但是理解了sstable的设计思想,对于了解其他数据库的底层存储也是有很大帮助的,因为很多思想是通用的。

接下来我们继续讲解,剩下的3大组件,重点是sstable;

3.4  SST文件

接下来介绍SSTable某个文件在磁盘上的结构,这对了解LevelDb的很有帮助。

LevelDb不同层级有很多SSTable文件(以后缀.sst为特征),所有.sst文件内部布局都是一样的。
刚才讲的Log文件是物理分块的,SSTable也一样会将文件划分为固定大小的物理存储块,但是两者逻辑布局大不相同;

根本原因是:Log文件中的记录是Key无序的,即先后记录的key大小没有明确大小关系,

而.sst文件内部则是根据记录的Key由小到大排列的,其中Key有序是设计.sst文件结构的关键。

 

 

Sstable由以下两个部分:数据存储区,数据管理区

 

数据存储区:包括dataBlock,存放实际的Key:Value数据

数据管理区:包括filter block,metaindex block,index block,footer,提供一些索引指针等管理数据,目的是更快速便捷的查找相应的记录。

data block:存储数据的block,每个sstable文件中有多个data block。
filter block和metaindex block:这两个block不一定存在于sstable,取决于Options中的filter_policy参数值,LevelDb 1.2版对于Meta Block尚无实际使用,只是保留了一个接口,估计会在后续版本中加入内容,不对这两部分进行讲解。
index block:存储的是索引数据,即可以根据index block中的数据快速定位到数据处于哪个data block的哪个位置。
footer:脚注数据,每个footer数据信息大小固定,存储一个sstable文件的元信息(meta data)。可以理解为索引的索引

 

接下来讲每个部分:
先看一下其中数据存储区中的单个data block 结构,它就像洋葱,需要一层一层拨开:

 

3.4.1  data block

从图中可以看出,其内部也分为两个部分:Block内容,Block尾部;
Block内容,是一个个KV记录,其顺序是根据Key值由小到大排列的,
在Block尾部则是一些“重启点”(Restart Point),其实是一些指针,指出Block内容中的一些记录位置。

我们需要先理解重启点:
看右图,我们可以把多个record分成多个组(看右下角图),每个组的第一个record就是一个重启点(看中间图,相当于每隔一段距离设置一个重启点)

目的:每隔一段距离设置一个重启点,也是防止第一个数据出错,导致后续数据全部出错,我把record的存储讲完,record的存储方式和重启点是相辅相成的,所以讲完record的存储方式,更好理解重启点)

这就需要我们看一下,record是怎么存储的?(目的:减少Key的存储量)

我们一再强调,Block内容里的KV记录是按照Key从小到大有序的,这样的话,相邻的两条记录很可能Key部分存在重叠
基于这个特性,为了减少Key的存储量,我们看看record的内部结构是什么样的?
其详细结构,每个记录包含5个字段:key共享长度,key非共享长度,value长度,key非共享内容,value内容;

 

看结构能感受到,record的存储,后边的记录,会依赖前边某一条记录,被依赖的那条记录,就是重启点(那么重启点的目的也就一目了然了)

 

上述说的存储方式:前缀压缩(prefix-compressed)方式。这种算法的原理是:针对一组数据,取出一个公共的前缀,而在该组中的其它字符串只保存非公共的字符串做为key即可,由于sstable保存KV数据是严格按照key的顺序来排序的,所以这样能节省出保存key数据的空间来

举个例子,感受一下:理解了record的存储方式,可以更好的理解重启点

key1=abc,key2=abcd,key3=abef,key4=acde,key5=bcde    首先key是有序的,从小到大排序;

“重启点”的意思是:在这条记录开始,不再采取只记载不同的Key部分,而是重新记录所有的Key值     

key1=abc作为重启点,整个key要记录下来,作为非共享部分key;

后续的,key2,3,4,会依据key1只存储不同的部分,相同的key前缀不需要存储;

key5=bcde作为新的重启点,后续的数据会依赖key5继续存储;


这里需要辨别一个误区,同样的数据,可以有多种前缀压缩方式,以下两种把key1作为重启点的方式,是错误的
方式一: 

方式二:   

最终data block的整体结果如下:

 

 

3.4.2  index block

接着看看 index block的内部结构,相对简单一些。

 

index block:存储的是data block的索引数据,即可以根据index block中的数据快速定位到数据处于哪个data block的哪个位置。

每条索引信息包含三个内容,以图上的数据块i的索引Index i来说:
红色部分的第一个字段记载 数据块i中 最大的那个Key值,(每个block中有多个从小到大的record,取最大的key,我们可以想一下它的作用)
第二个字段指出 数据块i在.sst文件中的起始位置(偏移量)
第三个字段指出Data Block i的大小(有时候是有数据压缩的)。

 

 

3.4.3  footer

metaindex_handle指出了metaindex block的起始位置和大小;

inex_handle指出了index Block的起始地址和大小;

这两个字段可以理解为索引的索引,是为了正确读出索引值而设立的,后面跟着一个填充区和魔数

 

 

3.5  Current文件

 

 

3.6  Manifest文件

Manifest就记载了SSTable各个文件的管理信息。结构比较简单:属于哪个Level,文件名称叫什么,最小key和最大key。   

 

 

到此,leveldb的6大组件,和其内部结构,我们讲完了!

接下来,看一下主要操作流程,后续更新。

 

 

相关内容快速导航:
一、LevelDB设计思想
二、levelDB整体框架,及memtable、log文件、immutable memtable  

三、levelDB整体框架之sstable,manfest文件,current文件

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值