leveldb 源码--总体架构分析

2023-11-13

一 本文目的

对leveldb的总体设计框架分析(关于leveldb基本原理,此文不做阐述,读者可以自行检索文章阅读即可),对leveldb中底层数据存储数据格式,内存数据模型,compact,版本管理,快照等机制实现介绍以及整个leveldb实现源码中各文件源码的职责,方便快速对leveldb有个总体的掌握

 

二 各特性机制的实现

  1.leveldb的底层数据格式存储

          leveldb底层数据格式,网上很多文章都有介绍,在此不做赘述,主要介绍一下上层怎么讲数据写入磁盘中。

   leveldb中k-v数据写入磁盘就是通过数据压缩写入的( CompactMemTable[内存压缩至sst] & BackgroundCompaction[层间sst文件压缩] ),上层都是通过TableBuilder对象来实现数据持久化的

           主要的两个接口:

           # Add:将一行记录加入一块buffer中

                   #Finish:将k-v的记录,按照table的格式(生成filter,metaindex,index,footer 块),然后分配对各块写入到sst文件中

   compact的使用大致过程:

     1.压缩过程中使用迭代器模式,按序遍历输入需要压缩的sst文件中key-val键值对。

     2. 丢弃key过期记录(比如:一个key的多次修改,只保留最新的一条记录,另外还有快照,这是后话),对没有过期的记录,将会调用TableBuilder.Add接口添加到TableBuilder的缓存区中,

     3. 直到缓存区中数据大小达到阈值(用户指定)。将会调用TableBuilder.Finish 生成sst表格式数据并持久化。

        2. 内存数据模型

    内存模型是使用跳表的数据结构的方式来进行管理维护的。

    # 跳表在leveldb中定义的是一个通用的数据结构,需要外部传入节点key的compare对象。

    #MemTable 使用组合的方式使用跳表,自定义compare对象。

    # 其中需要注意有意思的一点MemTable 存储到跳表结构中的节点是包含(key+val),跳表中key值得比较对象是通过外部定义传入的,MemTable使用的是下面的比较函数,从函数中可以看出需要对节点提取真正的userKey进行比较。

    

 

     3 Compact过程: 

          compact主要分为一下几步

           1.选择需要compact的level,通过VersionSet.PickCompaction函数来决定需要compact哪一层,改层哪些文件需要compact

     #至于为什么由VersionSet来决定,是因为VersionSet管理当前整个leveldb的文件组织结构等信息,后面再版本管理中会进行详细说明

          2.对需要compact的文件建立迭代器,迭代器按key的排序依次访问所有的记录

          3.依次遍历所有的记录,判断需要丢弃记录,对需要保留的记录,会调用TableBuilder.Add接口加入sst缓存区中

    记录丢弃的判断条件 

                  #同一个key非第一次出现,并且记录对应的序列号小于最旧的快照的序列号(说明该记录不需要快照备份)

                  # 该key值插入一个删除操作,并且不需要快照备份

          4.sst缓存区写满,就会生成一个完整的sst文件格式,然后持久化到磁盘上

    5.将压缩过程中涉及到的文件变更(例如:老sst删除,新sst生成)加入到版本管理中的version_edit中

              #注:此处不涉及老sst文件的清理,只是记录当前一次compact操作导致哪些文件需要被删除,真正删除操作由其他过程执行

          6.删除过期文件

              # 当前compact出来的新sst文件 & 所有版本version管理的sst文件,都会加入livefiles集合中

              #不在livefiles集合中的文件全部认为是过期文件,需要删除。

        

    4. 版本管理

   版本管理是leveldb中极其重要的模块,要想理解整个leveldb必须理解其为什么需要 & 如何实现版本管理的

   4.1 为什么需要版本管理

              1.假设一种场景:一个用户发起对某个sst文件读取操作,数据读取到了一半,此时compact完成,由于compact是独立的一个线程,此时sst文件会被清理掉了,此时用户读操作出错

    所以一句话就是:管理磁盘上的文件,保证leveldbdb数据的准确性

           4.2 如何实现版本管理

     基本概念:

      version :一个version对应一次数据文件变更的记录,比如compact会导致文件发现变化(老的sst文件,新生成sst文件),所以需要记录当前compact过程结束后,在当前数据库状态下有哪些文件,

        #主要数据结构:std::vector<FileMetaData*> files_[config::kNumLevels];记录管理每一层sst文件

      versionSet:由于每一次compact后都会产生一个version,所以需要将这些version管理起来,采用双向链表version按先后生成的顺序管理起来

      versionEdit:变化增量,每次compact时记录增量,主要是增加了哪些文件,需要删除哪些文件,通过上一次Version+versionEdit就会得到当前的Version

        #主要数据结构:

                                    #DeletedFileSet deleted_files_;

                                    #std::vector<std::pair<int, FileMetaData>> new_files_;

                实现大致思路是:
      每次在compact后生成versionEdit,然后通过调用versionSet.LogAndApply将versionEdit应用到当前版本生成最新的版本,然后加入versionSet链表中成为当前版本。
    
             # 几个问题:  
      1.版本管理的使用场景
        在每次对文件的使用(比如读)都会获取当前版本,然后会将该版本的引用计数+1,(读)完成后会将引用计数-1
       2.版本什么时候会被删除
         当一个版本没有了引用(最新版本在创建时引用计数自动+1,知道当下一个更新的版本加入是ref-1),系统会自动从versinSet的双向链表中摘除掉
          
       3.系统中每一次compact就会生成一个版本,是不是意味着compact多少次就会有多少次版本呢
         问题2中已经表明,一个版本的存活周期在于版本是否存在引用计数,如果没有了引用会立马被删除
    
  5.快照机制

     # 管理数据结构:快照双向链表,将所有的快照使用双向链表维护管理起来
     # 快照数据结构主要字段
          SnapshotImpl* prev_; //链表相关
           SnapshotImpl* next_; //链表相关
           const SequenceNumber sequence_number_; //快照的sequence_number_
      #实现的主要思想:
      leveldb中对于每次插入,系统维护一个全局自增的seq序列号,每一个key-val记录插入时都会带上该序列号,快照只需要获取当前一个seq序列号并将生成的快照加入快照列表中(防止compact时将已经打了快照的记录丢弃掉)。

      访问通过指定key & 快照序列号,系统先查找满足key值相同 && 记录序列号不能大于快照序列号的记录(持久化时相同key值记录是按照序列号有序存放的),返回给用户,从而实现快照。
                #如何保证快照的记录不被删除呢?
                     所有删除的过程只有compact时进行,compact逻辑中,遍历所有需要压缩的文件的key值,会判断该key能否丢弃
                     其中有一个条件是,如果当前key有快照引用,就不能compact掉,从而保证打了快照的数据不会被丢弃。

 三 源码结构

  主要通过源码的目录结构以及阐述关键目录和源文件的职责的方式来展示源码的整个架构。

    cmake:cmake的相关文件

    db:主要机制的实现,包括版本管理,compact,业务读写等功能机制实现;

    doc:文档;
    helpers/memenv:简单完全内存的文件系统,提供操作目录文件接口;
    include/leveldb:头文件,外部工程使用leveldb时引用的头文件;
    port:平台相关的实现,主要提供posix/android相关支持;
    table:定义了整个leveldb的持久化存储的数据结构
    util:通用功能实现。

主要介绍的是db & table,这两部分是整个leveldb的精髓

  table:完成了整个leveldb持久化层的数据格式的定义以及实现

    # block + block_builder  :定义了block格式以及block如何生成的实现,包括block块中重启点等技术细节,将block的访问抽象成对迭代器模式的访问

              # filter_block:定义了过滤器的实现

    # two_level_iterator & iterator_wrapper & iterator & merger & two_level_iterator:定义了各种迭代器,从而屏蔽底层数据访问细节

      #其中two_level_iterator:封装了索引迭代器和数据迭代器的操作,本质上是一个二重循环,来实现key的有序遍历

      for(遍历索引){

        for(遍历当前索引指向的block)

      }

      # table & table_build:定义了sst文件的数据格式以及如何生成sst的过程

 

  db:实现了包括上面提到的各种机制,主要包括版本管理,compact,容灾恢复等具体的实现细节

    #db_impl:定义个数据库的各种接口以及compact等数据库特性

    #log_format & log_reader & log_writer:定义了log文件格式和读写,此处的log文件用来实现备份容灾的功能的

              #memtable & skiplist:定义了leveldb如何使用跳表来实现数据在内存中的有序存储

    #snapshot:负责管理快照,使用链表的方式对快照进行管理

    #version_edit & version_set:负责版本管理的操作

    

 

             
 

    

   

      

 

转载于:https://www.cnblogs.com/chenhao-zsh/p/11616838.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

leveldb 源码--总体架构分析 的相关文章

  • 【Mysql】InnoDB 引擎中的页目录

    一 页目录和槽 现在知道记录在页中按照主键大小顺序串成了单链表 那么我使用主键查询的时候 最顺其自然的办法肯定是从第一条记录 也就是 Infrimum 记录开始 一直向后找 只要存在总会找到 这种在数据量少的时候还好说 一旦数据多了 遍历耗
  • Jenkins流水线怎么做?

    问CHAT Jenkins流水线怎么做 CHAT回复 Jenkins流水线是一种创建 测试和部署应用程序的方法 以下是为Jenkins创建流水线的步骤 1 安装Jenkins 首先你需要在你的服务器上安装Jenkins 这个过程可能会根据你
  • 【计算机毕业设计】病房管理系统

    当下 如果还依然使用纸质文档来记录并且管理相关信息 可能会出现很多问题 比如原始文件的丢失 因为采用纸质文档 很容易受潮或者怕火 不容易备份 需要花费大量的人员和资金来管理用纸质文档存储的信息 最重要的是数据出现问题寻找起来很麻烦 并且修改
  • Navicat 16 for MySQL:打造高效数据库开发管理工具

    随着数据的快速增长和复杂性的提升 数据库成为了现代应用开发中不可或缺的一部分 而在MySQL数据库领域 Navicat 16 for MySQL作为一款强大的数据库开发管理工具 正受到越来越多开发者的青睐 Navicat 16 for My
  • 【计算机毕业设计】实验室预约管理

    身处网络时代 随着网络系统体系发展的不断成熟和完善 人们的生活也随之发生了很大的变化 人们在追求较高物质生活的同时 也在想着如何使自身的精神内涵得到提升 而读书就是人们获得精神享受非常重要的途径 为了满足人们随时随地只要有网络就可以看书的要
  • 【计算机毕业设计】航空信息管理系统

    传统信息的管理大部分依赖于管理人员的手工登记与管理 然而 随着近些年信息技术的迅猛发展 让许多比较老套的信息管理模式进行了更新迭代 飞机票信息因为其管理内容繁杂 管理数量繁多导致手工进行处理不能满足广大用户的需求 因此就应运而生出相应的航空
  • Jenkins 插件下载速度慢、安装失败了!我教你怎么解决!

    Jenkins部署完毕 如果不安装插件的话 那它就是一个光杆司令 啥事也做不了 所以首先要登陆管理员账号然后点击系统管理再点击右边的插件管理安装CI CD必要插件 但是问题来了 jenkins下载插件速度非常慢 而且经常提示下载插件失败 真
  • 通俗易懂,十分钟读懂DES,详解DES加密算法原理,DES攻击手段以及3DES原理

    文章目录 1 什么是DES 2 DES的基本概念 3 DES的加密流程 4 DES算法步骤详解 4 1 初始置换 Initial Permutation IP置换 4 2 加密轮次 4 3 F轮函数 4 3 1 拓展R到48位 4 3 2
  • 步骤详图 教你在linux搭建容器环境

    警告 切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker 1 准备工作 系统要求 要安装Docker CE 社区版 操作系统的最低要求是CentOS7 7以下版本都不被支持 卸载旧版本 Docker改版
  • 基于java的物业管理系统设计与实现

    基于java的物业管理系统设计与实现 I 引言 A 研究背景和动机 物业管理系统是指对物业进行管理和服务的系统 该系统需要具备对物业信息 人员信息 财务信息等进行管理的能力 基于Java的物业管理系统设计与实现的研究背景和动机主要体现在以下
  • 基于java的物业管理系统设计与实现

    基于java的物业管理系统设计与实现 I 引言 A 研究背景和动机 物业管理系统是指对物业进行管理和服务的系统 该系统需要具备对物业信息 人员信息 财务信息等进行管理的能力 基于Java的物业管理系统设计与实现的研究背景和动机主要体现在以下
  • 深入了解 Python MongoDB 操作:排序、删除、更新、结果限制全面解析

    Python MongoDB 排序 对结果进行排序 使用 sort 方法对结果进行升序或降序排序 sort 方法接受一个参数用于 字段名 一个参数用于 方向 升序是默认方向 示例 按名称按字母顺序对结果进行排序 import pymongo
  • 【计算机毕业设计】电影播放平台

    电影播放平台采用B S架构 数据库是MySQL 网站的搭建与开发采用了先进的java进行编写 使用了springboot框架 该系统从两个对象 由管理员和用户来对系统进行设计构建 主要功能包括 个人信息修改 对用户 电影分类 电影信息等功能
  • 【计算机毕业设计】二手家电管理平台

    时代在飞速进步 每个行业都在努力发展现在先进技术 通过这些先进的技术来提高自己的水平和优势 二手家电管理平台当然不能排除在外 二手家电管理平台是在实际应用和软件工程的开发原理之上 运用java语言以及前台VUE框架 后台SpringBoot
  • 【ES6】解构语句中的冒号(:)

    在解构赋值语法中 冒号 的作用是为提取的字段指定一个新的变量名 让我们以示例 const billCode code version route query 来说明 billCode code version 表示从 route query
  • 【计算机毕业设计】OA公文发文管理系统_xtv98

    近年来 人们的生活方式以网络为主题不断进化 OA公文发文管理就是其中的一部分 现在 无论是大型的还是小型的网站 都随处可见 不知不觉中已经成为我们生活中不可或缺的存在 随着社会的发展 除了对系统的需求外 我们还要促进经济发展 提高工作效率
  • 做测试不会 SQL?超详细的 SQL 查询语法教程来啦!

    前言 作为一名测试工程师 工作中在对测试结果进行数据比对的时候 或多或少要和数据库打交道的 要和数据库打交道 那么一些常用的sql查询语法必须要掌握 最近有部分做测试小伙伴表示sql查询不太会 问我有没有sql查询语法这一块的文档可以学习
  • 服务器中E5和I9的区别是什么,如何选择合适的配置

    随着科技的进步 服务器处理器的性能在不断攀升 其中 Intel的E5和I9系列处理器在业界具有广泛的影响力 而当我们在选择服务器的时候会有各种各样的配置让我们眼花缭乱不知道该怎么去选择 下面我跟大家分享一下E5跟I9有什么区别 方便我们在选
  • Python 使用 NoSQL 数据库的优选方案

    NoSQL 数据库因其高性能 可扩展性和灵活性而风靡一时 然而 对于 Python 程序员而言 选择合适的 NoSQL 数据库可能会令人困惑 因为有多种选择可供选择 那么 哪种 NoSQL 数据库最适合 Python 呢 2 解决方案 根据
  • 网工内推 | 上市公司同程、科达,五险一金,年终奖,最高12k*15薪

    01 同程旅行 招聘岗位 网络工程师 职责描述 1 负责职场 门店网络规划 建设 维护 2 负责网络安全及访问控制 上网行为管理和VPN设备的日常运维 3 负责内部相关网络自动化和系统化建设 4 优化与提升网络运行质量 制定应急预案 人员培

随机推荐

  • idea的代码文本距离左边很远问题解决

    idea的代码文本距离左边很远问题解决 刚才看了篇文章 是关于idea 2021 1版本 看起来挺好 然后忍不住尝试了一下 但是不知道做了什么操作 突然代码的左边距离行号非常远 然后找了很多文章 也没找到解决办法 重新安装idea仍旧没解决
  • springboot2.0集成ShardingSphere-jdbc5.0-alpha所遇到的一些坑

    在springboot 2 5 3中配置使用ShardingSphere 5 0 alpha遇到了不少的坑 现在总结如下 1 没有使用shardingsphere jdbc core spring boot starter 在使用Shard
  • centos下安装apache

    下载所需要的包 wget http mirrors tuna tsinghua edu cn apache httpd httpd 2 4 54 tar gz wget http mirrors tuna tsinghua edu cn a
  • GnuTLS recv error (-110): The TLS connection was non-properly terminated问题的解决方案

    我在使用git clone branch 3 4 depth 1 https github com opencv opencv git命令的时候 遇到如下问题 fatal unable to access https github com
  • Radware负载均衡项目配置实战解析之一初识RADWARE(VIP与FARM配置)

    在近期的项目中 接触负载均衡设备RADWARE比较多 可能有很多朋友对这个设备还不是很了解 所以我把具体项目实战中的Radware配置应用与大家做一个分享交流 RADWARE是一家智能应用网络解决方案的全球领先供应商 主要生产应用交付和网络
  • Ubuntu下无法打开终端

    在安装某个版本的python并进行一系列自己也看不懂的配置之后 突然发现终端无法打开了 具体来说就是从桌面点击没有用 ctrl alt T也打不开 只能从选择文件夹 右击选择终端打开时可以 然后开始救赎之路 打开vscode的终端 或pyc
  • Python开发难学吗?简单易用适合初学者入门

    Python开发难学吗 适合初学者吗 Python入门阶段零基础学员打好基础是非常重要的 在非常高的抽象计算中 高级的Python程序设计非常难学 高级程序语言不等于简单 但对于初学者和完成普通任务Python语言是非常简单易用的 Pyth
  • 四、【服务器】服务器入门——常见单位

    U 高度单位 U 是UNIT的缩写 1U 4 445cm 是一种表示机架服务器外部尺寸的单位 指的是高度或者说厚度 规定这个尺寸是为了使得服务器保持适当的尺寸 在机柜安装的时候需要注意到留好安装高度 机架服务器通常宽度在19英寸 高度为1U
  • 小波分析

    本文首先介绍了从傅里叶变换到小波变换的发展史 然后着重强调了小波变换的两种作用 时频分析和多分辨率分析 最后讲了一下吉布斯效应等相关知识 FT 傅里叶变换 通过将信号分解成正余弦函数 把三角函数当做函数空间的基 将时域信号转化为频域信号 缺
  • Ubuntu16.04升级docker ce错误:Depends: libseccomp2 (>= 2.3.0) but 2.2.3-3ubuntu3 is to be installed

    环境 系统 Ubuntu16 04 docker old version Docker version 1 10 3 build 20f81dd 按照官方给出的步骤安装 https docs docker com install linux
  • DGL-kernel的变更(3)

    导读 DGL kernel中针对Graph的计算几个版本有了不小的变动 v0 3 0 4使用的是minigun v0 3和v0 4源码中主要相关部分则是在对应分支dgl src kernel目录下 v0 5中对kernel代码进行了重写 并
  • IOS学习笔记(十二)之IOS开发之表视图(UITableView)的相关类,属性与表视图实现学习(二)

    iOS学习笔记 十二 之IOS开发之表视图 UITableView 的讲解与使用 二 博客地址 http blog csdn net developer jiangqq 转载请注明地址 Author hmjiangqq Email jian
  • 记录一个问题maven jar 引入

    分模块创建项目jar包无法引入错误 明明在 确保错 无奈最后换个本地仓库地址 重新下载jar 结果不报错了 估计是jar包太多了 混乱导入造成的
  • MySQL中tinyint(1)与tinyint(2)的区别

    一 tinyint类型的介绍 1个tinyint类型的字段占用一个字节 一个int类型的字段占用四个字节 CREATE TABLE user id int 11 NOT NULL COMMENT ID age tinyint 1 NOT N
  • nginx配置SSL协议,80端口443端口。和非80/443端口

    1 80 443 server listen 80 server name www 域名 com rewrite https server name 1 permanent server listen 443 server name www
  • 前端项目查找网站有哪些?面试必看

    教你们一招 项目在这些地方找 面试官眼前一亮 还有一些面试技巧 收藏 工作年限 3 年工作经验 5个项目以上 2 年工作经验项目 4 个项目 技术栈 Vue vuex vue router webpack ES6 node vue reso
  • 兔子问题---细说斐波那契数列

    对于兔子问题的鼎鼎大名 相信很少有人没听过吧 为了完整性还是再说一下题目吧 题目描述 已知一对兔子每一个月可以生一对小兔子 而一对兔子出生后 第三个月开始生小兔子假如一年内没有发生死亡 则一对兔子开始 第N个月后会有多少对 这道题所描述的就
  • 解决IDEA2019.1.3无法创建包的子类包问题

    有时候我们需要创建包的子类包 空包 的时候我们发现 不知道如何在初始的包中创建子类包 随后在别的博客上看了好多解决方法 好多都是没有选中父类包 或者没有将下面这个选项勾掉 但是这个勾掉的话就把父类中最后一个包也变成了子类包 并没有达到我们所
  • “先裁掉女员工!”

    身为女性在职场 不得不面对一些尴尬的时刻 我朋友公司刚招了一个商务的妹纸 没几周就说自己怀孕了 紧接着 开启了三天打鱼两天晒网的请假模式 今年就业环境不太理想 朋友公司招人有严格的名额限制 考虑再三 上司和HR昨天找她面谈 上司说 市场岗压
  • leveldb 源码--总体架构分析

    一 本文目的 对leveldb的总体设计框架分析 关于leveldb基本原理 此文不做阐述 读者可以自行检索文章阅读即可 对leveldb中底层数据存储数据格式 内存数据模型 compact 版本管理 快照等机制实现介绍以及整个leveld