leveldb的SSTable文件layout设计

1. sst文件存储格式设计思想

【术语说明】

术语说明
data blockkv数据存储区域
index blockkv索引数据存储区域
blockdata/index block内按固定大小划分的块大小
restart重启点每间隔若干个kv对,存储一个完整的用户数据key。重复该过程(默认间隔值为16),每个重新存储完整key的点称之为restart pointer即restart重启点
record group每两个restart重启点区间称为record group

1. sst文件存储格式设计思想

1.1 单纯的只存放kv数据,如下图所示

在这里插入图片描述

我们知道sst文件的kv键值对是按照key有序进行存储,就像上图一样,但这种方式存在以下问题:

  • 很严重的读性能问题,因为查找任何一个key的value值都要从文件开头往后进行遍历一遍,最坏的时间复杂度为O(N)
  • 无法对原始数据进行二分查找,因为二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列,同时元素大小必须一样。
    基于以上原因,需要对原始数据建立索引。
1.2 建立索引后的SST文件存储格式

在这里插入图片描述

  • 在原数据的layout的基础上增加了一个index block区域,该区域主要存储索引信息,每条索引也是以kv键值对的形式存储的,key为用户kv数据block存储的第一条key的值,value为 用户kv数据block的offset,size
  • 为了sst文件加载时候能够自解释运行,因此需要有个固定的地方用来存放index block的信息,这里假设这个区域叫footer,其内容记录了index block在sst文件的offset以及size,这样sst加载的时候就知道从哪里加载index的内容了
  • 虽然建立了index block,但是本质的问题还是和1.1小节存在相同的问题
1.3 引入重启点加快block内部索引效率

在这里插入图片描述

  • 通过在block底部引入重启点结构(实际上就是顺序线性表结构),达到快速索引目的即高效的二分查找
  • 重启点记录是具体kv数据在block内偏移
  • 每个restart重启点是一个固定大小的元素用来记录offset数值
  • 因为重启点只记录的offset,所映射的真实的kv数据需要去sst文件中相应的block区域读取相应的值,因此为了加快查找的速度需要将数据先读到内存,然后在内存中进行遍历查找;
  • 当查找某个key时候,db是从把key所属的block块先拷贝到内存,然后在内存中遍历

key的查找过程:
在这里插入图片描述

1.4 空间优化
  • key的前缀压缩;因为key是按照顺序进行存储的,因此很大概率存在重复的部分,因此可以将重复的prefix进行压缩,以达到空间优化的目的;

    kv键值对的压缩存储格式:
    在这里插入图片描述

  • leveldb在index block对存储索引的key同样进行了优化;通过计算满足条件:

  1. last_block<last_key> < target < current_block<first_key>
  2. target长度最小,也是通过压缩key的长度来达到空间优化的目的
  • 压缩后的存储格式如下图所示:
    在这里插入图片描述
    如上图所示:
  1. 分别对用户数据进行了压缩存储,同时对sst索引数据的key值也做了一定的优化;
  2. 同时每个重启点记录是shared key length = 0的即存储的是完整的key值,因此在sstable中进行数据查找时,可以首先利用restart pointer点的数据进行键值比较,以便于快速定位目标数据所在的区域;另外也隐藏一个问题:一旦重启点损害那么整个record group的数据都无法恢复了,因此record group不能太大(每两个重启点之间区间叫record group)
  3. 这里为了方便举例每隔2个key进行一次重启点设置,即restart_interval=2
1.5 key查找优化之bloomfilter
  • 对于不存在的key,为了减少不必要的查找,需要记录key的状态
  • 防止空key攻击
  • bloomfilter存在一定的误判率,通过对hash函数个数以及存储元素个数的最优配置,保证最低的误差率
  • 同样为了支持bloomfilter的功能,在上面layout基础上增加meta区,同样为了meta自解释加载需在footer记录offset,size等信息
1.6 leveldb SSTable layout

图片来自于:
https://www.cnblogs.com/cobbliu/p/6194072.html
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值