数据结构篇:深度剖析LSM及与B+树优劣势分析

news2025/1/18 3:48:06

        本文旨在探讨LSM的特性及其在实际应用场景中的作用,同时对其与B+树进行比较,以帮助更好地理解和运用这两种数据结构。

什么是LSM(Log-structured Merge-tree)

        全称 Log-Structured Merge-Tree 日志结构合并树,但不是树,而是利用磁盘顺序读写能力,实现一个多层读写的存储结构,它是一种分层,有序,面向磁盘的数据结构,核心思想是利用了磁盘批量的顺序写要远比随机写性能高出很多,大大提升了数据的写入能力,但会牺牲部分读取性能为代价。

        其中HBase、LevelDB、ClickHouse这些NoSQL存储都是采用的类LSM树结构,该数据结构在 NoSQL 系统里非常常见,基本已经成为必选方案, 为了解决快速读写的问题去设计的充分利用了磁盘顺序写的特性,实现高吞吐写能力,数据写入后定期在后台Compaction在数据导入时全部是顺序append写,在后台合并时也是多个段merge sort后顺序写回磁盘。

深入理解

        首先,LSM是日志结构(Log-Structured)的,打印日志是一行行往下写,不需要更改,只需要在后边追加就好了。其次会进行合并树(Merge-tree),合并就是把多个合成一个,自上而下。基于以上特点,LSM-tree其实就是一个多层结构,像一个喷泉树一样,上小下大。

        专门为 key-value 存储系统设计的,最主要的就两个功能:1)写入put(k,v); 2)查找 get(k)得到v;
        首先是内存的 C0 层,保存了所有最近写入的 (k,v),这个内存结构是有序的,且可以随时原地更新,同时支持随时查询。接下去的 C1 到 Ck 层都在磁盘上,每一层都是一个有序的存储结构。降低一点读性能,通过牺牲小部分读性能,换来高性能写。

写入流程

        put 操作,首先追加到写前日志(Write Ahead Log)并更新其结构,然后加到C0 层。当 C0 层的数据达到一定大小,就把 C0 层 和 C1 层合并,这个过程就是Compaction(合并),合并出来的新的C1 会顺序写磁盘,替换掉原来的C1。当 C1 层达到一定大小,会和下层继续合并,合并后删除旧的,留下新的。

查询流程

        最新的数据在 C0 层,最老的数据在 Cn 层。就算查询也是先查 C0 层,如果没有要查的数据,再查 C1,逐层查下去直到最后一层。

以读换写不是个好方案?

        LSM树充分利用了磁盘顺序写的特性,实现高吞吐写能力,数据写入后定期在后台合并(Compaction),在数据导入时全部是顺序append写,在后台合并时也是多个段merge sort后顺序写回磁盘。针对写快读慢特点,比较适合那些数据插入操作远多于数据更新/删除/读操作的场景。但是问题来了,读能力应该是大部分存储系统最应该保证的能力,所以用读换写似乎不是个好方案。

针对该问题,为了提高读取性能,LSM Tree采用了多种优化方案

1)Bloom filter
           是一种带随机概率的bitmap,可以快速的判断某一个小树里有没有指定的那个数据
   避免了更多的IO查找,只需经过几个哈希函数计算就能知道数据是否在某个小树里
   查询效率得到了提升,但需要付出额外的存储空间,和维护布隆过滤器。

    直通车:布隆过滤器原理介绍和典型应用案例-CSDN博客

2)compact
           查询的时候去读取多个小树会有性能问题,通过后台进程不断地将小树合并到大树上
   程序查询的时候就可以直接读取大树,从而提高读取性能。

写入流程

        核心关键在于先将数据的操作存到内存中,由log记录,同时触发相关的更新,例如布隆过滤器,方便后续查询。当内存的MemTable达到阈值时通过归并排序方式合并放到磁盘队尾,防止内存因断电等原因丢失数据,写入内存的数据同时会顺序在磁盘上预写日志(WAL)。

        然后就是正常的put 操作,先是追加到写前日志(Write Ahead Log)并更新其结构,然后加到C0 层。当 C0 层的数据达到一定大小,就把 C0 层 和 C1 层合并,这个过程就是Compaction(合并),合并出来的新的C1 会顺序写磁盘,替换掉原来的C1。当 C1 层达到一定大小,会和下层继续合并,合并后删除旧的,留下新的。(关键在于更新布隆过滤器)

查询流程

        核心关键在于LSM Tree提升读性能的优化策略主要是使用布隆过滤器、多路归并机制。进行查询时,先检查布隆过滤器,如果布隆过滤器报告数据不存在,则直接返回不存在。在查询时,先使用二分搜索检索对应的稀疏索引/平衡二叉树,找到数据所在的范围,再读取磁盘上该范围内的数据。
        最新的数据在 C0 层,最老的数据在 Cn 层,查询也是先查 C0 层,如果没有要查的数据,再查 C1,逐层查下去直到最后一层。(关键在于查询布隆过滤器)

与 B/B+ tree的对比

B-Tree/B+Tree 
        关系型数据库均以 B-Tree/B+Tree作为其构建索引的数据结构,大量数据下 B/B+ tree 提供了比较高的查询效率,但B-Tree/B+Tree 的相应缺点插入或删除一条数据时,均需要更新索引,需要一次随机磁盘 IO,所以B+tree 只适用于频繁读、较少写的场景,如果在多写少读的场景下,将造成大量的随机磁盘 IO,导致性能骤降。
LSM tree 
        充分利用了磁盘顺序写的特性,实现高吞吐写能力,数据写入后定期在后台Compaction,在数据导入时全部是顺序append写,在后台合并时也是多个段merge sort后顺序写回磁盘,避免了高并发写场景下的磁盘 IO 开销,查询效率无法达到O(logn),但依然非常快。

        本质上来说,LSM tree 牺牲了一部分查询性能,换取较高的写入性能, 在key-value 型或日志型数据库是非常重要的。

        其缺点在于读写都进行了放大,读取数据时实际读取的数据量大于真正的数据量,因为在LSM树中需要先在C0查看当前key是否存在,不存在继续从Cn层中寻找。写入数据时实际写入的数据量大于真正的数据量,在LSM树中写入时可能触发Compact操作,导致实际写入的数据量远大于该key的数据量。

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

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

相关文章

5G随身wifi真实测评!飞猫5g随身wifi怎么样?飞猫5GVS格行5G随身wifi哪款网速快?5G随身wifi推荐品牌第一名!

飞猫5G随身wifi: 产品外观:黑色大气外观,净重175g,屏幕有信号和指示灯。 产品性能:采用展锐芯片。6根LDS天线,网速100-200mbps,网络延迟10-20ms,2.4G/5G双频可选,超稳定…

【gurobi】python调用gurobi创建范围约束

1.python调用gurobi创建范围约束 要在Python中使用Gurobi创建范围约束,您可以使用 addConstr() 方法,该方法允许您指定约束条件的下限和上限。下面是一个示例,演示了如何创建一个范围约束: 假设您有一个变量 x,您想要…

软考114-上午题-【计算机网络】-路由

一、路由 二、真题 真题1: 真题2: 真题3: 真题4: 真题5: 路由协议实际上是一种在路由器之间交换路由信息的协议。 路由协议让路由器了解整个网络的拓扑结构,包括哪些网络是直接相连的,哪些网络…

数据库重点知识(个人整理笔记)

目录 1. 索引是什么? 1.1. 索引的基本原理 2. 索引有哪些优缺点? 3. MySQL有哪几种索引类型? 4. mysql聚簇和非聚簇索引的区别 5. 非聚簇索引一定会回表查询吗? 6. 讲一讲前缀索引? 7. 为什么索引结构默认使用B…

练习题(2024/4/6)

1最接近的三数之和 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1: 输入:nums [-1,2,1,-4], target …

AI Agents产品图谱+网站合集

这个网站收集了市面受欢迎的项目,包括开源项目和闭源项目以及公司 地址:通过浏览列表中的AI代理项目和公司,社区里的创业者可以了解当前市场上的主要玩家和他们的产品特点,进行市场趋势分析和竞争分析。

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 🚀 Flutter作为一种跨平台的移动应用程序开发框架,为开发者提供了便利,使他们能够通过单一的代码库构建出高性能、高保真度的应用程序,同时支持Android和iOS两个平台。然而,完成Flutter应用程序的开发只是第一步…

LC 226.翻转二叉树

226. 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入: root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1] 示例 2: 输入: root [2,1,3] 输出&#xff1a…

VMware-16.0配置虚拟机网络模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、为什么要配置网络?二、配置步骤1.检查VMware服务2.进入配置页面3.添加网络模式1.Bridge2.NAT3.Host-only 4.DHCP租约5.静态IP 三、使用总结 前言…

ARM、X86、RISC-V三分天下

引入: 简单的介绍一下X86、ARM、RISC-V三种cpu架构的区别和应用场景。 目录 简单概念讲解 1. X86架构 2. ARM架构 3. RISC-V架构 应用场景 X86、ARM和RISC-V是三种不同的CPU架构,它们在设计理念、指令集和应用场景上有一些区别。 简单概念讲解 1. X…

计算机语言 之【C++】入门级知识讲解(命名空间,C++输入输出,缺省参数,函数重载,引用,内敛函数,auto关键字,for循环,指针空值nullptr)

三点睡六点起,阎王夸我好身体 不到三点我不睡,太平间里抢C位 一、命名空间 1.命名空间的作用 2.命名空间定义 3.命名空间使用 二、C的输入输出 1.输入输出说明介绍 2.std命名空间的使用惯例 三、缺省参数 1.缺省参数概念 2.缺省参数分类 四、…

华为激光雷达真的遥遥领先吗?华为激光雷达详细拆解和系统方案分析(55图)

华为作为中国自动驾驶技术第一梯队的卓越代表,其激光雷达产品也备受瞩目,不过关于华为激光雷达的公开资料非常少,即便是有也非常粗略。 本文通过详细拆解华为96线激光雷达产品,尝试分析华为激光雷达的技术方案,并通过…

八股面试速成—Java语法部分

暑期实习面试在即,这几天八股和算法轮扁我>_ 八股部分打算先找学习视屏跟着画下思维导图,然后看详细的面试知识点,最后刷题 其中导图包含的是常考的题,按照思维导图形式整理,会在复盘后更新 细节研究侧重补全&a…

如何给上百张图片一键添加圆角?

一,为什么要给图片做圆角? 随着数字化时代的到来,图片已经成为我们日常生活中不可或缺的一部分。无论是社交媒体上的个人分享,还是商业宣传中的产品展示,图片都扮演着重要的角色。而在图片的呈现方式中,圆…

【第五篇】使用BurpSuite设定条目范围

【1】在对一个网站进行合法观察、测试的过程中,加载出的HTTP历史条目是十分繁多的,于是,对请求进行排序、过滤等显得至关重要。 我们可以单击#实现HTTP条目的升序或降序,这样我们可以在顶部看到最先或最旧的请求。 【2】通常HTTP条目中包含对多个站点的请求,若我们只想观…

SV学习笔记(七)

类型转换 写在前面 类型转换可以分为 静态转换和动态转换 。静态转换即需要在转换的表达式前 加上单引号 即可,该方式并不会对转换值做检查。如果发生转换失败,我们也无从得知。动态转换即需要使用 系统函数$cast(tgt, src) 做转换。静态转…

如何在 Mac 上恢复已删除的数据

如果您丢失了 Mac 上的数据,请不要绝望。恢复数据比您想象的要容易,并且有很多方法可以尝试。 在 Mac 上遭受数据丢失是每个人都认为永远不会发生在他们身上的事情之一......直到它发生。不过,请不要担心,因为您可以通过多种方法…

手机扫码获取文件怎么做?文件活码在电脑上的制作方法

现在很多人会把文件生成二维码之后,将二维码图片打印或者分享给其他人,通过扫描二维码的方式快速在手机上查看或者下载文件内容,从而提升文件传输的速度和效率。 制作文件活码二维码可以长期有效的扫码显示文件,支持多个文件存入…

nginx配置实例(反向代理)

目录 一、目标-反向代理实现效果 二、安装tomcat 三、配置nginx服务 四、配置反向代理 一、目标-反向代理实现效果 访问过程分析: 二、安装tomcat 1、安装jdk环境 新建/export/server目录 解压jdk 查看是否解压成功 配置jdk软连接 进入jdk的bin目录中&#x…

【Docker系列】在 Linux 上安装 Docker Compose 的简明步骤

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…