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 源码--总体架构分析 的相关文章

  • 自定义编写zabbix_agent脚本

    vi usr lib systemd system zabbix agent servicce Unit Description Zabbix Agent After syslog target After network target S
  • 【Mysql】InnoDB 引擎中的页目录

    一 页目录和槽 现在知道记录在页中按照主键大小顺序串成了单链表 那么我使用主键查询的时候 最顺其自然的办法肯定是从第一条记录 也就是 Infrimum 记录开始 一直向后找 只要存在总会找到 这种在数据量少的时候还好说 一旦数据多了 遍历耗
  • 如何解决Mybatis-plus与Mybatis不兼容的问题:An attempt was made to call a method that does not exist. The attempt

    博主猫头虎的技术世界 欢迎来到 猫头虎的博客 探索技术的无限可能 专栏链接 精选专栏 面试题大全 面试准备的宝典 IDEA开发秘籍 提升你的IDEA技能 100天精通Golang Go语言学习之旅 领域矩阵 猫头虎技术领域矩阵 深入探索各技
  • 【计算机毕业设计】个人日常事务管理系统

    进入21世纪网络和计算机得到了飞速发展 并和生活进行了紧密的结合 目前 网络的运行速度以达到了千兆 覆盖范围更是深入到生活中的角角落落 这就促使 管理系统的发展 管理系统可以实现远程处理事务 远程工作信息和随时追踪工作的状态 网上管理系统给
  • 【计算机毕业设计】线上招聘问答系统

    计算机网络发展到现在已经好几十年了 在理论上面已经有了很丰富的基础 并且在现实生活中也到处都在使用 可以说 经过几十年的发展 互联网技术已经把地域信息的隔阂给消除了 让整个世界都可以即时通话和联系 极大的方便了人们的生活 所以说 线上招聘问
  • 【计算机毕业设计】网上拍卖系统

    现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本网上拍卖系统就是在这样的大环境下诞生 其可以帮助使用者在短时间内处理完毕庞大的数据信息 使用这种软件工具可以帮助管理人员
  • Linux终端常见用法总结

    熟悉Linux终端的基础用法和常见技巧可以极大提高运维及开发人员的工作效率 笔者结合自身学习实践 总结以下终端用法供同行交流学习 常 见 用 法 1 快捷键 1 1 Alt 在光标位置插入上一次执行命令的最后一个参数 1 2 Ctrl R
  • 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
  • 软件测试|SQLAlchemy环境安装与基础使用

    简介 SQLAlchemy 是一个强大的 Python 库 用于与关系型数据库进行交互 它提供了高度抽象的对象关系映射 ORM 工具 允许使用 Python 对象来操作数据库 而不必编写原生SQL查询 本文将介绍如何安装 SQLAlchem
  • 什么是充放电振子理论?

    CHAT回复 充放电振子模型 Charging Reversal Oscillator Model 是一种解释ENSO现象的理论模型 这个模型把ENSO现象比喻成一个 热力学振荡系统 在这个模型中 ENSO现象由三个组成部分 充电 Char
  • 电商数据api拼多多接口获取商品实时数据价格比价api代码演示案例

    拼多多商品详情接口 接口接入入口 它的主要功能是允许卖家从自己的系统中快速获取商品详细信息 通过这个接口 卖家可以提取到商品的各类数据 包括但不限于商品标题 价格 优惠价 收藏数 下单人数 月销售量等 此外 还可以获取到商品的SKU图 详情
  • 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析

    在 MongoDB 中 我们使用 find 和 find one 方法来在集合中查找数据 就像在MySQL数据库中使用 SELECT 语句来在表中查找数据一样 查找单个文档 要从MongoDB的集合中选择数据 我们可以使用 find one
  • 【计算机毕业设计】微信小程序反诈科普平台

    相比于以前的传统手工管理方式 智能化的管理方式可以大幅降低反诈科普平台的运营人员成本 实现了反诈科普平台的标准化 制度化 程序化的管理 有效地防止了反诈科普平台的随意管理 提高了信息的处理速度和精确度 能够及时 准确地查询和修正反诈科普 一
  • Oracle EBS AP发票导入 API Rejection List 第二部分

    Oracle EBS AP发票导入 API Rejection List 第二部分 The report lists the reason the invoice could not be imported and prints a bri
  • Kubernetes (十一) 存储——Secret配置管理

    一 简介 从文件创建 echo n admin gt username txt echo n westos gt password txt kubectl create secret generic db user pass from fi
  • 面试官问,如何在十亿级别用户中检查用户名是否存在?

    面试官问 如何在十亿级别用户中检查用户名是否存在 前言 不知道大家有没有留意过 在使用一些app注册的时候 提示你用户名已经被占用了 需要更换一个 这是如何实现的呢 你可能想这不是很简单吗 去数据库里查一下有没有不就行了吗 那么假如用户数量
  • 30天精通Nodejs--第二十天:express-操作mysql

    目录 前言 安装依赖并配置MySQL连接 安装mysql2库 配置连接信息 在Express应用中使用MySQL 结合Express路由实现CRUD操作 整合到主应用 结语 前言 在Node js中使用Expre
  • UI自动化测试之Jenkins配置

    背景 团队下半年的目标之一是实现自动化测试 这里要吐槽一下 之前开发的测试平台了 最初的目的是用来做接口自动化测试和性能测试 但由于各种原因 接口自动化测试那部分功能整个废弃掉了 其中和易用性有很大关系 另外 也和我们公司的接口业务也有关
  • Python 使用 NoSQL 数据库的优选方案

    NoSQL 数据库因其高性能 可扩展性和灵活性而风靡一时 然而 对于 Python 程序员而言 选择合适的 NoSQL 数据库可能会令人困惑 因为有多种选择可供选择 那么 哪种 NoSQL 数据库最适合 Python 呢 2 解决方案 根据

随机推荐

  • 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