当前位置:网站首页 > 技术博客 > 正文

leveldb(一文彻底搞懂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

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

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

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

  • 文件大小
  • 最大key值
  • 自小key值
    版本信息十分关键,除了在查找数据时利用两个key值来加快查找,还在其中为了一些compaction的统计值来控制compaction的进行。
    可以看到文件的元数据主要包含最小和最小key
 

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

 

当每次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这些记录。最终可以得到一个上次运行结束时的版本信息。

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

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

版权声明


相关文章:

  • linuxcp命令使用方法2024-10-30 22:00:59
  • monkey测试(推荐一款好用的APP性能测试工具——Monkey!)2024-10-30 22:00:59
  • 代码对比工具(🛠️在线代码比较工具-轻松查找代码差异🔍)2024-10-30 22:00:59
  • 数据库有哪些?2024-10-30 22:00:59
  • 前端实现权限管理2024-10-30 22:00:59
  • 线程池java原理2024-10-30 22:00:59
  • iframe(【HTML】深入全掌握 iframe:了解 its 技术原理、优缺点、最佳应用场景及实战指南)2024-10-30 22:00:59
  • monkey测试(超详细的Monkey测试介绍)2024-10-30 22:00:59
  • c语言函数参数为指针2024-10-30 22:00:59
  • sql获取上一条数据2024-10-30 22:00:59