当前位置: 首页 > news >正文

leveldb源码剖析(二)——LSM Tree

LSM Tree

LSM Tree:Log-Structured Merge Tree,日志结构合并树。是一种频繁写性能很高的数据结构。

LSM Tree将写入操作与合并操作分离,数据首先写入磁盘中的日志文件(WAL),随后写入内存缓存,内存中的数据是有序的,通常使用的方式如跳表、红黑树等。内存中的数据按照策略刷新至磁盘,由于内存中的数据有序,存储至磁盘中的数据也是有序的,相较于随机写,顺序写提高了性能。磁盘中的数据根据策略进行合并,删除旧的数据,避免数据持续增长,同时提高了查询性能。

存储结构

在这里插入图片描述

  • WAL:当有新的 key-value需要写入时,首先将其追加到顺序写的日志文件(WAL)中,因为WAL中的数据与当前内存中的KV数据一致,可以利用WAL文件恢复上一次程序的运行状态。当immutable memtable中的内容写入SSTable后,删除WAL文件,重新创建一个空的WAL文件(此处根据实际情况实现);
  • memtable:内存中的数据结构,保证存储数据有序,通常使用跳表、红黑树等,leveldb中使用的跳表;
  • immutable memtable:内存中的数据结构,不可修改的表,memtable中的key数据达到一定的阈值时,memtable变为immutable memtable,然后创建一个新的memtable。引入immutable memtable可以有效避免 memtable 的读写冲突竞争,从而避免阻塞,提高系统性能;
  • Minor Compact:
    • 将immutable memtable的数据写入磁盘的流程,在Level 0生成一个新的SSTable;
    • 当某个 Level 中的 SSTable 文件数量或容量达到阈值时,会触发该 Level 文件和下一个 Level 文件的合并操作,这个过程会生成新的SSTable文件删除旧的SSTable文件;
  • SSTable:数据持久化到磁盘后的数据结构,保存的是排序后的数据。每个SSTable包含多个存储数据的文件,成为segment,每个segment内部是有序的,由于是追加写,不用的SSTable可能存在相同的key;

在这里插入图片描述

数据写入

数据写入的流程如下:

  1. 写入日志文件(Write-Ahead Log, WAL)
当有新的 key-value需要写入时,首先将其追加到顺序写的日志文件中。这个操作称为预写日志(Write-Ahead Logging),用于系统崩溃时数据的还原,保证了数据的一致性和可靠性。
  1. 写入Memtable
将新的key-value写入内存中的数据结构,数据结构通常为跳表或红黑树,保证了数据的有序性。数据读取时有限读取Memtable,如Memtable中存在,可以迅速响应,提高了读取性能。
  1. Memtable to SSTable
当内存中写入的数量达到一定的阈值时,将内存中的数据写入到磁盘的SStable的segmnet中,此过程写入的数据是有序的。
  1. SSTable的合并
SSTable可以根据一定的策略进行合并,如时间、文件大小或其他条件,合并操作过程中,消除重复的key和已经删除的key,生成新的SSTable文件。

数据读取

  1. 查询memtable,如查询不到,查询mmutable memtable;
  2. 查询mmutable memtable,如查询不到,查询SSTable;
  3. 查询SSTable;
查询SSTable时,通常从最新的segment扫描,扫描全部segment直至查询到对应数据。当扫描某个特定的segment时,由于该segment内部的数据是有序的,因此可以使用二分查找的方式,在O(logn)的时间内得到查询结果。但对于二分查找来说,要么一次性把数据全部读入内存,要么在每次二分时都消耗一次磁盘 IO,当 segment 非常大时,这两种情况的代价都非常高。通常使用稀疏索引的方式优化查询策略。

稀疏索引

在这里插入图片描述

上图为kafka利用稀疏索引查询的机制。

稀疏索引的原理是将数据切分成多个小块,以多个小块作为一个单位,由于数据有序性,仅需将每个单位开头的数据作为索引即可。

有了稀疏索引,我们可以现在索引表中利用二分法快速定位要查询的key在哪个数据块中,仅从磁盘中读取这一小块数据即可获取查询结果,IO代价较小。

稀疏索引虽然提高了查询性能,但是当查询结果不在SSTable中时,我们不得不扫描完所有的segment,针对这种情况,通常使用布隆过滤器解决该问题。

布隆过滤器是一种空间效率极高的算法,能够快速地检测一条数据是否在数据集中存在。我们只需要在写入每条数据之前先在布隆过滤器中登记一下,在查询时即可断定某条数据是否缺失。

布隆过滤器的内部依赖于哈希算法,当检测某一条数据是否见过时,有一定概率出现假阳性(False Positive),但一定不会出现假阴性(False Negative)。也就是说,当布隆过滤器认为一条数据出现过,那么该条数据很可能出现过;但如果布隆过滤器认为一条数据没出现过,那么该条数据一定没出现过。这种特性刚好与此处的需求相契合,即检验某条数据是否缺失。

文件合并

文件合并的目的主要是控制存储数据大小,LSM Tree可以按照一定的策略执行文件合并,合并后的旧数据会被删除,合并后的新数据是有序的,合并过程中会消除重复键、删除键以及更新过期键。

在这里插入图片描述

数据删除

LSM tree设计一个特殊的标志位,称为 tombstone(墓碑),删除一条数据就是把它的 value 置为tombstone,如上图所示,在执行文件合并时被删除的数据在合并过程中被清除掉。

合并过程中如存在重复的key,通常根据key的时间戳或其他合并策略决定保留哪个版本的数据。

优缺点

  • 具有较高的写入性能和压缩存储,适用于写多读少或写入速度较快的场景。通过将写入操作集中在内存和顺序写的日志文件中,可以获得较高的写入吞吐量。查询性能也较好,通过内存缓存和有序的SSTable文件,可以快速定位和检索键值对。
  • 合并操作可能会引起较长的停顿时间,对于实时性要求较高的系统可能会有影响。

总结

  • LSM Tree具有较高的写入性能,主要通过写入内存和磁盘顺序写实现;
  • 写入数据时,先将数据写入内存,当内存达到一定大小时,将内存中的数据一次性顺序写入(flush)磁盘,生成SSTable中一个segment,segment内部数据也是有序的;
  • 读取数据时,先查找布隆过滤器,如查询不到直接返回key不存在,如存在,继续查询稀疏索引表;
  • 查找稀疏索引表,根据查询到的范围从磁盘读取数据,进而利用二分法读取获取最终结果;
  • Segment过多的情况下,会导致写性能下降,通过文件合并操作,消除重复键、删除键以及更新过期键,避免产生大量的segment文件,达到了数据压缩的目的,同时也提高了查询效率;

参考:

https://zhuanlan.zhihu.com/p/640477369

https://hzhu212.github.io/posts/2d7c5edb

https://cloud.tencent.com/developer/article/2011084

相关文章:

leveldb源码剖析(二)——LSM Tree

LSM Tree LSM Tree:Log-Structured Merge Tree,日志结构合并树。是一种频繁写性能很高的数据结构。 LSM Tree将写入操作与合并操作分离,数据首先写入磁盘中的日志文件(WAL),随后写入内存缓存,…...

三十六、Gin注册功能-检查账号是否存在

一、初始化 1、在cms.go中添加数据库连接方法 func connDB(app *CmsApp) {mysqlDB, err : gorm.Open(mysql.Open("root:rootroottcp(localhost:3306)/?charsetutf8mb4&parseTimeTrue&locLocal"))if err ! nil {panic(err)}db, err : mysqlDB.DB()if err !…...

什么是期权对冲?

今天期权懂带你了解什么是期权对冲?期权对冲的选择取决于投资者的市场预期和风险承受能力,通过合理使用期权对冲策略,可以有效减少风险并优化投资组合的表现。 期权对冲是什么? 期权是一种支持双向交易的投资产品,期…...

什么是数据库课程设计?

文章目录 前言一、课程设计目的二、课程设计流程三、设计要点四、示例项目总结 前言 数据库课程设计是一个综合性的实践过程,旨在通过实际项目的设计与实现,加深学生对数据库理论知识的理解和应用能力。 以下是一个关于数据库课程设计的基本框架和要点&…...

走进低代码报表开发(二):高效报表设计新利器

在前面的文章中,我们已经详细介绍了勤研低代码开发平台的报表数据源可视化设计,接下来,让我们一起来继续了解勤研低代码平台的报表设计,在当今数字化快速发展的时代,高效便捷的开发工具对于企业和开发者来说至关重要。…...

校园水电费管理|基于java的校园水电费管理小程序系统 (源码+数据库+文档)

校园水电费管理 目录 基于java的校园水电费管理小程序系统 一、前言 二、系统设计 三、系统功能设计 小程序端 后台功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕…...

java设计模式 桥接模式

桥接模式(Bridge Pattern)是一种结构型设计模式,旨在将抽象部分与其实现部分分离,使它们都可以独立地变化。桥接模式通过将继承改为组合,实现了在不修改现有类的情况下,动态地切换和扩展抽象类与其具体实现…...

如何利用大数据技术来识别和预防网络赌博行为?

1.构建赌博账户识别模型:通过大数据分析和机器学习技术,建立智能风险防控体系,对账户进行全生命周期管理,精准打击和切断不法分子的资金链条 。 2.分析资金流动:利用大数据技术监测和分析异常资金流动,识别…...

N-152基于java贪吃蛇游戏5

开发工具eclipse,jdk1.8 文档截图: N-152基于java贪吃蛇游戏5...

从线段中搜寻提取闭合轮廓(三)

1.前言 做底层和数据的调试问题也是个麻烦事,如果没有方便的可视化工具辅助,那将令人感到痛苦,借助可视化的工具可以让我们高效、省心,进而心情舒畅,重要的是可以提高调试效率。 当然可视化工具也分不同层次的…...

最全面的递归算法详解,一篇足矣(高手必备)

在编程中,递归和循环是两种常用的控制结构,各有其独特的优缺点。理解这两者的特点和应用场景,对于编写高效、可读的代码至关重要。 什么是递归? 递归是一种强大的编程技术,允许函数在其定义中调用自身。递归通常涉及…...

数据结构(2)单向链表排序和双向链表操作

一单向链表的插入排序 void insertion_sort_link(link_t* plink) { // 如果链表头为空,直接返回 if(NULL plink->phead) { return; } // 初始化指针,p指向当前已排序部分的最后一个节点 node_t* p plink->phead; // ptemp指向待插入的…...

OpenCV结构分析与形状描述符(14)拟合直线函数fitLine()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 拟合一条直线到2D或3D点集。 fitLine 函数通过最小化 ∑ i ρ ( r i ) \sum_i \rho(r_i) ∑i​ρ(ri​)来拟合一条直线到2D或3D点集&#xff0c…...

Mysql基础练习题 1757.可回收且低脂的产品(力扣)

编写解决方案找出既是低脂又是可回收的产品编号。 题目链接: https://leetcode.cn/problems/recyclable-and-low-fat-products/description/ 建表插入数据: Create table If Not Exists Products (product_id int, low_fats ENUM(Y, N), recyclable …...

Nginx调优,有这篇就够了

目录 1. 工作进程数量 2. Nginx最大打开文件数 3. Nginx事件处理模型 4. 开启高效传输模式 5. 连接超时时间 6. proxy调优 7. fastcgi 调优 8. gzip 调优 9. expires 缓存调优 10. 防盗链 11. 内核参数优化 1. 工作进程数量 #根据cpu个数自动调整工作进程数量 work…...

Java语言程序设计基础篇_编程练习题*18.17 (数组中某个指定字符出现的次数)

题目:*18.17 (数组中某个指定字符出现的次数) 编写一个递归的方法,求出数组中一个指定字符出现的次数。需要定义下面两个方法,第二个方法是一个递归的辅助方法。 public static int count(char[] chars, char ch) public static int count(…...

实时(按帧)处理的低通滤波C语言实现

写在前面: 低通滤波采用一般的FIR滤波器,因为本次任务,允许的延迟较多,或者说前面损失的信号可以较多,因此,涉及一个很高阶的FIR滤波器,信号起始段的信号点可以不处理,以及&#xf…...

Centos7.9部署Gitlab-ce-16.9

一、环境信息 软件/系统名称版本下载地址备注Centos77.9.2009https://mirrors.nju.edu.cn/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.isogitlab-cegitlab-ce-16.9.1https://mirror.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.9.1-ce.0.el7.x86_64.rpm…...

卷积神经网络(一)

目录 一.卷积神经网络的组成 二.卷积层 目的: 参数: 计算公式 卷积运算过程 三.padding-零填充 1.Valid and Same卷积 2.奇数维度的过滤器 四.stride步长 五.多通道卷积 1.多卷积核(多个Filter) 六.卷积总结 七.池化层(Pooling) 八.全连接层…...

加密与安全_ sm-crypto 国密算法sm2、sm3和sm4的Java库

文章目录 Presm-crypto如何使用如何引入依赖 sm2获取密钥对加密解密签名验签获取椭圆曲线点 sm3sm4加密解密 Pre 加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签 sm-crypto https://github.com/antherd/sm-crypto 国密算法sm2、sm3和sm4的java版。基于js…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...