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

news2024/9/24 13:22:57

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2105214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 SpannableString 在 Android 开发中是一个非常强大的工具,它允许你在单个字符串范围内应用多种样式。使用 SpannableString&#xf…

【 C++ 】 类和对象的学习 (二)

😘我的主页:OMGmyhair-CSDN博客 目录 I、类的默认成员函数 一、构造函数 二、析构函数 三、拷贝构造函数 四、 运算符重载 赋值运算符重载 五、取地址重载_普通对象 六、取地址重载_const对象 I、类的默认成员函数 用户没有显示实现&#xff0…

Linux学习笔记5 值得一读,Linux(ubuntu)软件管理,搜索下载安装卸载全部搞定!(上)

本文记录Ubuntu操作系统的软件包管理。 一、背景 整个Linux系统就是大大小小的软件包构成的,在linux系统中,软件的管理非常重要,与其他操作系统不同,linux的软件包管理比较复杂,有时还需要处理软件包之间的冲突。本文…

Python | 泰勒图

写在前面 最近,开始对于CMIP6的一些数据进行评估。Talor图是一个很好展现模式间误差的方式,这里简单记录一下在python中的实现方式。 主要为半图的画法 参考的代码为: https://zenodo.org/records/5548061 效果大致下面这个样子 这边在原…

maven中如何配置多个仓库使其同时生效

场景 有一个项目&#xff0c;我把代码跟本地maven依赖包从同事那里拷贝过来&#xff0c;然后打包却一直打不了&#xff0c;一直报aliyun仓库找不到这个依赖的错误&#xff0c;无论我改成引用本地仓库还是线上aliyun仓库都不行。 依赖 <dependency><groupId>org.spr…

有三层交换机就不用路由器了?真的假的

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 晚上好&#xff0c;我的网工朋友。 在现代企业网络环境中&#xff0c;三层交换机因其高效的数据包处理能力和较低的延迟而受到广泛欢迎。 然而&…

Python 从入门到实战7(元组)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 之前的文章我们通过举例学习了python 中列表的定义及相关操作。今…

Echarts大屏可视化

构建可视化大屏&#xff1a; 构建布局&#xff1a;通过css和html对整个页面进行模块拆分&#xff0c;控制好每一张图的位置和大小&#xff0c;再将echarts实例化对象放到不同的盒子里 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en&quo…

斯普林格-《土木工程与结构抗震设计》 Springer-Civil Engineering and Structural Seismic Design

文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网&#xff1a;https://ais.cn/u/vEbMBz提交检索&#xff1a;EI Compendex、IEEE Xplore、Scopus最终截稿&#xff1a;2024年9月2日23:59 三、大会介绍 四…

关于vue中v-model绑定radio表单元素的说明

在学习中&#xff0c;老师讲在v-model中&#xff0c;绑定的是radio的checked属性&#xff0c;起初看了例子后很不理解&#xff0c;于是开始寻找答案 老师所说的绑定关系 老师给的绑定代码&#xff0c;怎么看来&#xff0c;都不是实例的gender变量绑定radio的checked属性&…

2024 MongoDB 中国用户大会上海站成功举办圆满结束: 技术驱动未来,携手共创辉煌

一年一度 2024 MongoDB 中国用户大会上海站顺利举办&#xff0c;感谢大家的积极参与&#xff01; 在数字化浪潮的背景下&#xff0c;随着人工智能、物联网、5G等前沿技术的快速发展&#xff0c;如何利用这些技术实现业务创新&#xff0c;已成为中国企业在激烈市场竞争中保持领…

Vivado+PetaLinux 系统搭建教程

PetaLinux 是基于 Yocto project DDR SDRAM 双倍数据率同步动态随机存取存储器&#xff08;英语&#xff1a;Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;简称DDR SDRAM&#xff09;为具有双倍资料传输率的SDRAM&#xff0c;其资料传输速度为系统主…

Matplotlib | 绘制饼图

目录 简介安装 Matplotlib开始绘制简单饼图添加标签添加百分比修改显示方式突出扇形设置标题修改颜色实践&#xff1a;绘制七大洲面积比例图 简介 饼图&#xff08;Pie Chart&#xff09;&#xff0c;用扇形的面积&#xff0c;也就是圆心角的度数来表示数量。 饼图能够十分直…

【Java】ApiPost请求返回 `406` 状态码(jackson)

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述3.1 问题截图3.2 错误简介3.2.1 HTTP状态码 406 Not Acceptable3.2.2 序列化和反序列化 3.3 后端问题位置…

yaml文件查看模型的架构

最近在看hrnet模型代码&#xff0c;想查看hrnet的模型架构&#xff0c;输出一下&#xff0c;但是模型参数需要cfg&#xff0c;我就想着怎么把yaml文件导进来然后打印模型呢&#xff0c;直接chat就可以了&#xff0c;下面解释一下每一部分&#xff0c;非常的好理解 yaml文件格式…

传神论文中心|第24期人工智能领域论文推荐

在人工智能领域的快速发展中&#xff0c;我们不断看到令人振奋的技术进步和创新。近期&#xff0c;开放传神&#xff08;OpenCSG&#xff09;传神社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自…

ChatGPT 3.5/4.0使用手册:解锁人工智能的无限潜能

1. 引言 在人工智能的浪潮中&#xff0c;ChatGPT以其卓越的语言理解和生成能力&#xff0c;成为了一个革命性的工具。它不仅仅是一个聊天机器人&#xff0c;更是一个能够协助我们日常工作、学习和创造的智能伙伴。随着ChatGPT 3.5和4.0版本的推出&#xff0c;其功能和应用范围…

3个免费好用的网站,可以转换PDF,提取MP3

今天分享的三个网站&#xff0c;分别用于文件转换PDF&#xff0c;QMC转MP3格式和配色网站。 TOPDF 这个网站是一个在线PDF转换工具&#xff0c;可以快速将文本文件、演示文稿、电子表格和图片转换为PDF格式。它支持多种文件格式&#xff0c;如AZW3、BMP、CHM、CSV、DjVu、DOC、…

秋招突击——算法练习——8/30、9/4——技巧题练习——复习{}——新作{只出现一次的数字、多数元素、颜色分类、下一个排列、寻找重复数}

文章目录 引言复习新作136、只出现一次的数字个人实现 169、多数元素个人实现 75、颜色分类个人实现参考实现 31、下一个排列个人实现参考实现 287寻找重复数个人实现参考实现 总结 引言 手撕的代码大部分都是出自于这里&#xff0c;还是要继续加强&#xff0c;把剩下一些零碎…

10分钟学会Jmeter的用法

一提到接口测试&#xff0c;通常大家会有这样的疑问&#xff1a;前端测试不是已经覆盖到各种业务逻辑了吗&#xff1f;为什么还要做接口测试&#xff0c;接口测试和前端测试是不是重复了&#xff1f;对于这个问题&#xff0c;可以从下面几个方面来解释&#xff1a; 什么是接口…