leveldb

leveldb是一个写性能十分优秀的存储引擎,是典型的LSM-tree的实现。LSM的核心思想是为了换取最大的写性能而放弃掉部分读性能。那么,为什么leveldb写性能高?简单来说它就是尽量减少随机写的次数。leveldb首先将数据更新到内存中。当内存中的数据量达到一定阈值,将这部分数据再真正刷新到磁盘文件中。一般来说,顺序写60MB/s,随机写45MB/s.

整体架构


leveldb主要由以下几个重要的部件构成:
1.memtable
2.immutable memtable
3.sstable
4.manifest
5.current
6.log

memtable

刚才提到leveldb的一次写入操作并不是直接将数据写入到磁盘文件,而是采用先将数据写入内存的方式。所以,memtable就是一个内存中进行数据组织与维护的结构。在memtable中,数据按用户定义的方法排序之后按序存储。等到其存储内容到达阈值时(4MB)时,便将其转换成一个不可修改的memtable,与此同时创建一个新的memtable来供用户进行读写操作。memtable底层采用跳表,它的大多数操作都是O(logn)。

immutable memtable

当memtable的容量达到阈值时,便会转换成一个不可修改的memtable即immutable memtable。它同memtable的结构定义一样。两者的区别只是immutable memtable是只读的。immutable memtable被创建时,leveldb的后台压缩进程便会利用其中的内容创建一个sstable,然后持久化到磁盘中。

sstable

leveldb虽然采用了先写内存的方式来提高写效率。但是内存中的数据不可能是无线增长,并且日志中记录的写入操作过多会造成异常发生,而且恢复时间过长。因此内存中的数据达到一定容量就得将数据持久化到磁盘中。除了某些元数据文件,leveldb的数据主要都是通过sstable来存储的。
虽然在内存中,所有的数据都是按序排列的,但是当多个memtable数据持久化到磁盘后,其对应的sstable之间是存在交集的,这样造成在读操作时得对所有的sstable文件进行遍历,严重影响了读效率。所以,leveldb会定期整合这些文件,也叫做compaction。随着compaction的进行,sstable文件在逻辑上被分成若干层。通过内存数据直接dump出来的是level 0 层文件,后期整合出来的level i层文件。sstable本身是不可修改的。

manifest

在leveldb中有个版本的概念。一个版本记录了每一层所有文件的元数据。元数据包括如下几点:

  • 文件大小
  • 最大key值
  • 自小key值
    版本信息十分关键,除了在查找数据时利用两个key值来加快查找,还在其中为了一些compaction的统计值来控制compaction的进行。
    可以看到文件的元数据主要包含最小和最小key
// tFile holds basic information about a table.
type tFile struct {fd         storage.FileDescseekLeft   int32size       int64imin, imax internalKey
}

版本则维护了每一层所有文件的元数据信息。入下代码所示:

type version struct {s *session // session - versionlevels []tFiles // file meta// Level that should be compacted next and its compaction score.// Score < 1 means compaction is not strictly needed. These fields// are initialized by computeCompaction()cLevel int // next levelcScore float64 // current scorecSeek unsafe.Pointerclosing  boolref      intreleased bool
}

当每次compaction完成时,leveldb都会创建一个新的version。compaction完成简单来说就是sstable的新增或者减少。而version创建的规则是:
versionNew = versionOld + versionEdit
这里的versionEdit指的是在旧版本基础上变化的内容。一般指sstable的增加或者删除。
manifest文件就是用来记录这些versionEdit信息的。一个versionEdit数据会编码成一条记录写入到manifest文件中。如下图所示

一共有两条versionEdit记录,每条记录包括

  1. 新增哪些sstable文件
  2. 日志文件编号
  3. 删除哪些sstable文件
  4. 当前compaction的下标
  5. 操作seqNumber等信息
    通过这些信息,leveldb变可以启动时创建一个空的version,不断apply这些记录。最终可以得到一个上次运行结束时的版本信息。

current

主要是记录当前manifest 的文件名。为什么需要这个?因为leveldb每次启动时,都会创建一个新的manifest文件,因此会出现很多个manifest文件。current则用来指出那个才是我们需要关心的文件。

log

leveldb写操作不是直接写入磁盘,而是先写入内存。加入写入到内存的数据还未来得及持久化,leveldb发生异常或者服务器宕机等会造成写入的数据丢失。因此,leveldb在写入内存之前会首先将所有的写操作写入日志文件中。每次写操作都是一次顺序写入,这样写效率高,整体写入性能好。此外,leveldb写操作的原子性也可以通过log来实现。
异常情况主要有以下几种:
1.写log完成,写内存未完成
2.写log期间进程异常
3.write操作完成后(写日志、写内存都完成)异常
4.immutable memtable持久化过程异常
5.其它压缩异常
第2种情况发生,数据库重启读取log时,发现异常日志数据则丢弃该条日志数据,即视作这次用户写入失败
第1、3、4情况发生时,都可以通过读取redo日志文件中记录的写入操作来完成数据库的恢复。

一文彻底搞懂leveldb架构相关推荐

  1. 一文彻底搞懂前端监控 等推荐

    大家好,我是若川.话不多说,这一次花了几个小时精心为大家挑选了20余篇好文,供大家阅读学习.本文阅读技巧,先粗看标题,感兴趣可以都关注一波,一起共同进步. 前端点线面 前端点线面 百度前端研发工程师, ...

  2. 一文快速搞懂Kudu到底是什么

    文章目录 引言 文章传送门: Kudu 介绍 背景介绍 新的硬件设备 Kudu 是什么 Kudu 应用场景 Kudu 架构 数据模型 分区策略 列式存储 整体架构 Kudu Client 交互 Kud ...

  3. layer output 激活函数_一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)...

    在"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)"中我们详细介绍了BP算法的原理和推导过程,并且用实际的数据进行了计算演练.在下篇中,我们将自己实现BP算法(不使用第 ...

  4. opc服务器是硬件吗,opc是什么(一文彻底搞懂什么是OPC)

    原标题:(opc是什么(一文彻底搞懂什么是OPC)) opc是什么(一文完全搞懂什么是OPC)从2000年终以来,我们就一直在运用OPC软件互操纵性范例,而那些正准备踏入和想要踏入工业自动化范畴的人们 ...

  5. 10分钟带你彻底搞懂微内核架构

    文章目录 十分钟搞懂系列 什么是微内核架构? 如何实现微内核架构? 总结 十分钟搞懂系列 序号 标题 链接 1 10分钟带你彻底搞懂企业服务总线 https://blog.csdn.net/belon ...

  6. 一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)

    在"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)"中我们详细介绍了BP算法的原理和推导过程,并且用实际的数据进行了计算演练.在下篇中,我们将自己实现BP算法(不使用第 ...

  7. 一文彻底搞懂Mybatis系列(十六)之MyBatis集成EhCache

    MyBatis集成EhCache 一.MyBatis集成EhCache 1.引入mybatis整合ehcache的依赖 2.类根路径下新建ehcache.xml,并配置 3.POJO类 Clazz 4 ...

  8. 手写简易版 React 来彻底搞懂 fiber 架构

    React 16 之前和之后最大的区别就是 16 引入了 fiber,又基于 fiber 实现了 hooks.整天都提 fiber,那 fiber 到底是啥?它和 vdom 是什么关系? 与其看各种解 ...

  9. 一文彻底搞懂ROC曲线与AUC的概念

    一文彻底搞懂ROC曲线与AUC的概念 1. ROC曲线的初级含义 1.1 精确率和召回率 1.2 ROC曲线的含义 2. ROC曲线如何绘制 3. ROC曲线和排序有什么关联? 4. AUC和基尼系数 ...

最新文章

  1. mysql opti_MySQL基础操作
  2. rmmod: can't change directory to '/lib/modules': No such file or directory问题解决
  3. 等差素数列(素数筛暴力)
  4. python爬虫面试题
  5. 定位到元素后获取其属性_Selenium界面自动化测试(4)(Python):元素定位及操作...
  6. json解析数组 nlohmann_json解析数组 nlohmann_Nlohmann json学习
  7. (转)Hibernate框架基础——映射普通属性
  8. 电脑硬件知识学习_计算机的发展史,你对硬件知识了解多少,带大家了解一下....
  9. SSL数字证书的签发及使用(服务器证书)
  10. 计算机组成原理本科生期末试卷答案,计算机组成原理本科生期末试题.doc
  11. com.android.gallery3d文件夹,如何在Android Gallery3D(cooliris)中显示特定文件夹?
  12. Python学习_100Days
  13. 英语发音规则---/ŋ/与/ŋg/的读音区别
  14. 这可能是世界第一座海上漂浮城市,浑身都是黑科技!
  15. Learning Deep Features for Discriminative Localization
  16. python网络数据采集 第二版_Python网络数据采集 (影印版)第2版
  17. 2020版KALI安装教程
  18. 京东有鸿蒙系统app,刘强东力挺华为鸿蒙,安卓版京东与鸿蒙版京东,差距不是一点点...
  19. 枪火——古龙之视觉化
  20. 【uni-app】uni-app实现聊天页面功能——功能篇(下)

热门文章

  1. FileInputStream中read()及read(byte b[])的用法
  2. 网络流和棒球赛淘汰问题 公平分配模板 足球联赛 UVa1306 The K-League
  3. vue自定义表单设计器思路
  4. linux快捷命令设置
  5. android Launcher3 动态设置一个快捷图标(添加快捷图标)
  6. JavaWeb细节——jstl导入eclipse报错
  7. [Unity] Generic 模式的动画混合和移动方向发生错误的解决办法:使用 Humanoid 模式
  8. Smoothing Images
  9. STM32CubeMX GCC工程Makefile内容详解
  10. WinAPI: OffsetRect - 移动矩形