SST文件

定义

sst 文件是用来持久化数据库数据的文件,LevelDB 使用的就是sst文件, 其充分考虑了持久化,读写性能和存储空间的权重

设计

设计模式

接口设计

创建文件

sst 文件由原始数据经过序列化后存入磁盘,因此需要进行编码和解码,那么采用策略模式,创建编码器进行编码

检索文件

首先考虑到仅在 sst 文件中进行读取,有多种读取方式,那么可以采用迭代器模式读取数据

初始化

当第一次启动 DB 时,需要恢复数据索引,所以还需要进行数据库的初始化

编码

基本结构

一段编码需要 类型,长度,数据本身,当我们把长度和数据合并,就会变成变长编码(例如 c h a r char char 数组用结尾是 0 0 0 表示字符串结束)
我们考虑如何遍历一段数据,记录一段数据的总长度,再按顺序记录组成数据的每个元素的长度,就可以用一段二进制编码还原出初始数据,记录长度的数组我们暂时称为 o f f s e t offset offset

sst 文件的编码

sst 为了提高查询新能,在编码中加入了索引,为了更清晰的描述数据,引入了元数据段
sst 文件编码分为三部分,元数据,索引段,数据段

元数据

更复杂的描述一段数据的类型,支持事物,时间戳,是否删除等
其数组组成由 数据类型,索引长度,数据长度 组成

索引段

索引段由 布隆过滤器offset 组成
布隆过滤器用来快速检索当前 sst 文件中是否存在目标数据,offset 用来二分查找 数据段中的数据

数据段

数据段存储 kv 对

数据格式

sst 将 数据分成 data 区域 和 index 区域依次存入

data 区域

data 区域所有的 key 是递增的
考虑到较多数据下,data区域会变的非常大,主存无法存下一个sst文件,那么将data分为许多block,每个block有各自的布隆过滤器,对所有的block抽象出索引,这样查询时只需要读入索引,由索引找到对应的block
data区域由许多 block 组成

sst编码设计

KV对

存储了 kv 的 size,这样拿到一块 kv 就可以解析出 key 和 value,无需在外部设立索引
kv 的 size一般较小,为了节省空间使用了 binary 的变长编码

type KVStruct struct {
	KeySize   uint64
	ValueSize uint64
	Key       []byte
	Value     *Utils.ValueStruct
}

block

由上到下存储,offset 存储每个 kv 结构的地址
由于需要在 block 上二分查找,我们将 kv 的地址拿出来做成索引

type block struct {
	KV       []KVStruct
	kvOffset []uint64
	count    uint64
}

index

每一个 index 存储了对应 block 的信息,前面 block 的设计为知道开头位置即可解码,现在我们只知道文件的头和尾,为了二分时的便捷,将 block 设计为了在文件开头顺序排列,且block 内的信息可以顺序解码,index紧跟在block后面,index内的信息可以顺序解码

type index struct { //一个index 描述一个block
	blockOffset uint64
	maxVersion  uint64
	KeyCount    uint64
	filter      *Utils.Bloom
}

缺点

没有设计统一的编码方式,代码耦合度高(当时已经写了一大半不想改了)

sst

现在我们希望只读取索引,那么我们就需要每个索引的 offset,因为每个索引的大小不同(内置布隆过滤器),那么我们可以将索引的offset固定大小并放到文件末尾

type SSTable struct { // block 在前, index 在后,目的是可以在索引上二分,然后直接读取一个block
	Blocks     []block
	Ind        []index
	IndOffset  []uint64
	blockCount uint64
}

内存映射

在 Linux 中,调用系统的 IO 接口时,系统会先将数据放入磁盘缓存中,积累一定程度后再放入磁盘中,也就是将数据从用户态的内存读到内核态的内存再进行磁盘读写,其目的是解决大量小数据存储问题
但是我们已经精心设计过了数据的结构,希望直接存入磁盘

mmap

Linux 针对上述情况提供了 mmap,实现物理地址和虚拟地址的一一映射关系,调用 mmap 同步函数后相当于直接将数据存入磁盘

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值