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

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滤波器,信号起始段的信号点可以不处理,以及…...

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…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...