LevelDB的源码阅读(一)
源码下载
git clone https://github.com/google/leveldb.git
项目结构
- db/, 数据库逻辑
- doc/, MD文档
- helpers/, LevelDB内存版, 通过namespace覆盖
- port/, 平台相关代码
- table/, LSM有关的
主要模块
Log 文件
客户端的写请求会先 append 到 Log 文件,成功后再写入到 Memtable。如果宕机可以通过 Log 文件来恢复 Memtable。
Memtable 和 Immutable Memtable
内存数据结构,基于跳表。客户端的读写请求都会由 Memtable 处理。 当 Memtable 占用的内存达到一定阈值,重新生成新的 Memtable 处理客户端请求。原来的 Memtable 转成 Immutable Memtable,等待归并到 SST 文件中。
SST 文件
落地到磁盘的存储文件。SST 分为不同的 level,具体参考文档。
Manifest 文件
Manifest 记录不同 level 的 SST 文件,包括每个 SST 文件的 key range、大小等 metadata。
Current 文件
Current 记录了最新的 Manifest 文件。
LSMtree的核心思想以及问题
在LSM Tree中,所有数据直接写入memtable并打log, 当memtable足够大的时候, 变为immemtable, 开始往硬盘挪, 成为SSTable. 你可以用任何有道理的数据结构来表示memtable, immemtable和SSTable. LevelDB选择用跳跃表(skiplist)实现memtable和immemtable, 用有序行组来实现SSTable。
LSM Tree存在如下问题:
1.适用于插入多而查找少的情况。在查找key时,最坏情况要从memtable读到immemtable, 再到所有SSTable.
2.SSTable要怎么有效merge(major compaction)? 如果只有一个SSTable, 我要把新immemtable归并进去, 就要重写这个SSTable. 数据有多大, 这个SSTable也会有多大.那么把SSTable分成若干份, 每份2MB呢?在最坏的情况下,比如,当前这个immemtable恰好永远有一个key与任意SSTable中至少一个key重复,就回到刚刚重写全库的情况了.
针对以上问题,LevelDB打了两个增强补丁:
1. 添加BloomFilter, 这样可以提升全库扫描的速度, 直接跳过没有这个key的SSTable.
2. leveled compaction, 把SSTable分成不同的等级. 除等级0以外, 其余各等级的SSTable不会有重复的key.
LevelDB的做法让每次compaction波及到的范围是可预期的. 官方文档的说法是"The compaction picks a file from level L and all overlapping files from the next level L+1". 只按等级延迟合并,没有任何随机读写操作, 机制上简单, 而且不需要bookkeeping,可以优雅得释放被删除记录的空间。
需要注意的是:因为下级可能还有相同key的数据,因此,compaction不一定会清空所有deletion maker.
参考文献:
1.https://zhuanlan.zhihu.com/p/27329248
2.http://masutangu.com/2017/06/leveldb_1/
LevelDB的源码阅读(一)的更多相关文章
- LevelDB的源码阅读(二) Open操作
在Linux上leveldb的安装和使用中我们写了一个测试代码,内容如下: #include "leveldb/db.h" #include <cassert> #in ...
- LevelDB的源码阅读(三) Put操作
在Linux上leveldb的安装和使用中我们写了这么一段测试代码,内容以及输出结果如下: #include <iostream> #include <string> #inc ...
- LevelDB的源码阅读(四) Compaction操作
leveldb的数据存储采用LSM的思想,将随机写入变为顺序写入,记录写入操作日志,一旦日志被以追加写的形式写入硬盘,就返回写入成功,由后台线程将写入日志作用于原有的磁盘文件生成新的磁盘数据.Leve ...
- LevelDB的源码阅读(三) Get操作
在Linux上leveldb的安装和使用中我们写了这么一段测试代码,内容以及输出结果如下: #include <iostream> #include <string> #inc ...
- LevelDB(v1.3) 源码阅读之 Arena(内存管理器)
LevelDB(v1.3) 源码阅读系列使用 LevelDB v1.3 版本的代码,可以通过如下方式下载并切换到 v1.3 版本的代码: $ git clone https://github.com/ ...
- LevelDB(v1.3) 源码阅读之 Slice
LevelDB(v1.3) 源码阅读系列使用 LevelDB v1.3 版本的代码,可以通过如下方式下载并切换到 v1.3 版本的代码: $ git clone https://github.com/ ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
随机推荐
- SourceTree使用图解
看完这篇文档你能做到的是: 1.简单的用Git管理项目. 2.怎样既要开发又要处理发布出去的版本bug情况. SourceTree是一个免费的Git图形化管理工具,mac下也可以安装. 下载地址:ht ...
- 【C++札记】类的分离式写法
介绍 类的分离式写法,使得代码更加规范,增强了阅读性. 分离式写法的规则: 1.类的变量:写在类的里面 2.成员函数:类中写函数的声明,函数的定义写在类体外. 3.写在类外函数定义时,类名前加限定(O ...
- 题解 CF437C
基本思路---贪心 既然要求最小代价,当用一定顺序删除时代价一定最小,不难发现,每次都删去x,y中最小的,最后的总代价业一定最小! 因此就可以写出下面的简单的代码 代码 #include<ios ...
- js 颜色随机切换
生成随机颜色 方法1:RGB模式 function randomColor1() { var r=Math.floor(Math.random()*256); var g=Math.floor(Mat ...
- S03_CH09_DMA_4_Video_Switch视频切换系统
S03_CH09_DMA_4_Video_Switch视频切换系统 9.1概述 本例程详细创建过程和本季课程第一课<S03_CH01_AXI_DMA_LOOP 环路测试>非常类似,因此如果 ...
- gin shoudBind
GET 请求 a_b POST aB或者AB //json大小写aB或者AB,form 表单 下划线a_b
- Base64编码为什么会使数据量变大
现在工作中把视频转成base64发现数据量过大无法下载. 1.为什么base64编码会使数据量变大呢? Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码.它将需要编码的数据 ...
- 在论坛中出现的比较难的sql问题:7(子查询 判断某个字段的值是否连续)
原文:在论坛中出现的比较难的sql问题:7(子查询 判断某个字段的值是否连续) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以 ...
- 分布式事务(ACID特性、CAP定律)
普通事务和分布式事务的区别: 普通事务就是一般所说的数据库事务,事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成.当事务被提交给了DBMS(数据库管理系统),则DBMS(数 ...
- ArrayList和CopyOnWriteArrayList(转载)
这篇文章的目的如下: 了解一下ArrayList和CopyOnWriteArrayList的增删改查实现原理 看看为什么说ArrayList查询快而增删慢? CopyOnWriteArrayList为 ...