SSTable是leveldb 的核心模块,这也是其称为leveldb的原因,leveldb正是通过将数据分为不同level的数据分为对应的不同的数据文件存储到磁盘之中的。为了理解其机制,我们首先看看SSTable中的基本概念。

首先看看数据的整体存储结构:

可以从图中看到了几个概念:Datablock,Metablock, MetaIndex block, Indexblock, Footer.具体他们的含义可以大致解释如下:

1. Datablock,我们知道文件中的k/v对是有序存储的,他们被划分到连续排列的Data Block里面顺序存储起来;

2. 紧跟数据存储区的是Meta Block,存储的是Filter信息,比如Bloom过滤器,用于快速判断key是否在对应数据块;

3. MetaIndex Block是对Meta Block的索引,它只有一条记录,为meta index的名字(也就是Filter的名字)和指向meta Block的BlockHandle;

4. Index block是对Data Block的索引,对于其中的每个记录,其key >=Data Block最后一条记录的key,同时<其后Data Block的第一条记录的key;value是指向data index的BlockHandle;

5. 最后的是一个定长的Footer,他包含了MetaIndex block和Indexblock 的BlockHandle,以及填充区和一个magic数字。其逻辑格式如下图

了解了每个块的大致作用以后,我们再来详细分析每个组成部分,首先是Datablock其总体格式如下图

Block data存储的就是我们leveldb中最关键的数据KV对,而type是一个标记Block data是否采用了Snappy压缩算法,crc32顾名思义则是整个block的一个crc校验值,用于判断block是否出错。知道整体结构以后我们再来看看具体的block data部分的存储格式:

也许你会以为在划分好block的数据存储区域以后那么就是一个一个的KV对(如图中的Record)了,但是其实不是,leveldb为了降低数据的存储量和快速的查找引入了一个重启点(restartpoint)的概念。这里的restart是指kv对的K的重现完整存储的概念,我们来看看每个record的存储格式以理解这里的restartpoint这个概念。

在leveldb中每一个KV对被分为了如上图的几个部分,因为Block内容里的KV记录是按照Key大小有序的,所以相邻的两条记录之间的Key很可能存在一个相同的部分,比如key i=“the Car”,Key i+1=“the color”,那么两者存在相同部分“the c”。leveldb就可以利用这个相邻记录存在相同部分来尽量减少Key的存储量,比如Key i+1可以只存储和上一条Key不同的部分“olor”,两者的共同部分从Key i中可以获得。所以整个存储区就存在这样的一个存储情况:一条记录存储完整的Key,而之后的记录开始连续一定的记录数都采取只记载不同的Key部分,然后在是一个重新存储完整的Key值的记录,然后再是一定数量的存储不完整Key的记录,那么我们就称这里的存储完整的Key值的记录为重启点。所以上面的图中的Restart就是用来记录这些存储完整Key的Record的地址,而num_restarts则更容易理解了,就是我们这个block中一共有多少个这样存储了完整Key的Record。

倒过去理解,最后我们首先看本block有多少个存储了完整Key的记录,然后这些记录的位置在那里,然后根据这些位置信息就可以定位到完整KV对,举个例子如下:

|||test comm|onn
|||hahaa|haha
|||testtest1|xxxx
|||tttt|tttt
开始
第三条记录的偏移量
2

将上面的展开就可以得到记录为

test comm|onn
test hahaa|haha
testtest1|xxxx
testtttt|tttt

下一篇文章将从代码的角度进行分析

leveldb源码分析--SSTable之逻辑结构的更多相关文章

  1. leveldb源码分析--SSTable之block

    在SSTable中主要存储数据的地方是data block,block_builder就是这个专门进行block的组织的地方,我们来详细看看其中的内容,其主要有Add,Finish和CurrentSi ...

  2. leveldb源码分析--SSTable之TableBuilder

    上一篇文章讲述了SSTable的格式以后,本文结合源码解析SSTable是如何生成的. void TableBuilder::Add(const Slice& key, const Slice ...

  3. LevelDB源码分析-sstable的Block

    sstable中的Block(table/block.h table/block.cc table/block_builder.h table/block_builder.cc) sstable中的b ...

  4. leveldb源码分析--SSTable之Compaction

    对于compaction是leveldb中体量最大的一部分,也应该是最为复杂的部分,为了便于理解我们首先从一些基本的概念开始.下面是一些从doc/impl.html中翻译和整理的内容: Level 0 ...

  5. Leveldb源码分析--1

    coming from http://blog.csdn.net/sparkliang/article/details/8567602 [前言:看了一点oceanbase,没有意志力继续坚持下去了,暂 ...

  6. leveldb源码分析--WriteBatch

    从[leveldb源码分析--插入删除流程]和WriteBatch其名我们就很轻易的知道,这个是leveldb内部的一个批量写的结构,在leveldb为了提高插入和删除的效率,在其插入过程中都采用了批 ...

  7. leveldb源码分析--Key结构

    [注]本文参考了sparkliang的专栏的Leveldb源码分析--3并进行了一定的重组和排版 经过上一篇文章的分析我们队leveldb的插入流程有了一定的认识,而该文设计最多的又是Batch的概念 ...

  8. leveldb源码分析--日志

    我们知道在一个数据库系统中为了保证数据的可靠性,我们都会记录对系统的操作日志.日志的功能就是用来在系统down掉的时候对数据进行恢复,所以日志系统对一个要求可靠性的存储系统是极其重要的.接下来我们分析 ...

  9. leveldb源码分析之Slice

    转自:http://luodw.cc/2015/10/15/leveldb-02/ leveldb和redis这样的优秀开源框架都没有使用C++自带的字符串string,redis自己写了个sds,l ...

随机推荐

  1. php -- 获取函数参数

    ----- 015-parameter.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv=&q ...

  2. logstash-2-插件配置

    配置语法:  Logstash必须有一个 input 和一个 output 1, 处理输入的input 1), 从文件录入 logstash使用一个名为 filewatch的 ruby gem库来监听 ...

  3. vim 常用命令(一)特殊删除

    dd 可以删除光标当前行: ndd  n代表行数,3dd,删除从当前光标往下3行: di 删除在指定符号内的内容,如 空号,引号内: dt 删除当前光标到指定符号的内容

  4. (转)request.getSession()几种获取情况之间的差异

    一.三种情况 HttpSession session = request.getSession(); HttpSession session = request.getSession(true); H ...

  5. vue的项目优化---回顾

    陆陆续续也用vue开发或重构了不少项目,在这期间遇到不少的坑,也尝试过优化.在此记录一下,想到一点算一点吧: 一.尽可能的减少watcher的数量   当监听数据是一个对象的时候,最好具体到监听对象的 ...

  6. iOS开源项目周报0413

    由OpenDigg 出品的iOS开源项目周报第十六期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. glidin ...

  7. 设置了winform的背景图片随窗体的变化而变化

    private void mainform_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; System.Drawi ...

  8. Spring基础(9) : 自动扫描

    一  配置xml方式:扫描com包下的bean <?xml version="1.0" encoding="UTF-8" ?> <beans ...

  9. HDFS 操作命令总结

    1 hadoop fs   这个是FS  shell 提供的 .上传下载文件  查看文件大小 改变文件权限都用这个命令. 具体命令的 用法可以到这个文档来查询 http://hadoop.apache ...

  10. vue 教程

    1.安装 nodejs,检测 nodejs 环境(node -v). 2.安装vue-cli脚手架npm install vue-cli -g 3.在电脑的某个盘中创建项目,之后进入该项目. 4.初始 ...