LSM-Tree数据结构原理

news2024/9/18 13:13:52

LSM-Tree树原理

什么是LSM-Tree

LSM-Tree 即 Log Structrued Merge Tree,这是一种分层有序,硬盘友好的数据结构。核心思想是利用磁盘顺序写性能远高于随机写。

LSM-Tree 并不是一种严格的树结构,而是一种内存+磁盘的多层存储结构。HBase、LevelDB、RocksDB这些 NoSQL 存储都使用了 LSM-Tree。

LSM-Tree简介

LSM Tree(Log Structure Merge Tree)是一种数据结构,是一种基于日志追加写、有一定结构、并且会merge合并的树(数据结构)

特点

  • 利用磁盘批量的顺序写要远比随机写性能高出很多来支持随机读写操作
  • 更适用于写多读少类型的场景
  • 广泛应用在各大 NoSQL 中。比如基于 LSM 树实现底层索引结构的 RocksDB,就是 Facebook 用 Golang 对 LevelDB 的实现,Hbase也是用LSM-Tree的数据结构实现的
LSM的组成部分

在这里插入图片描述

MemTable

MemTable 是 LSM-Tree 在内存中的数据结构,只用于保存最新的数据,按照 Key 有序地组织这些数据。

LSM-Tree 没有规定用怎样的数据结构实现 MemTable,例如 HBase 使用跳表来保证内存中 Key 的有序性。

存在内存中的数据会因为断电丢失,所以我们通常使用 WAL,即预写日志的方式来保证数据的可靠。

WAL: 预写日志,即事务的所有修改在提交之前要先写入 log 文件中

Immutable MemTable

MemTable 达到一定大小后,会转化为 Immutable MemTable。Immutable MemTable 是将 MemTable 转为磁盘上的 SSTable 的一种中间状态。

转化过程中写操作由新的 MemTable 处理,过程中不阻塞数据更新操作。

SSTable

SSTable 是有序键值对集合,是 LSM 树在磁盘中的数据结构。它是一种持久化、有序且不可变的键值村存储结构

SSTable 内部包含一系列可配置大小的 Block 块。这些 Block 的 index 会被存储在 SSTable 的尾部,用于帮助快速查找特定的 Block。当一个 SSTable 被打开时,index 表会被加载到内存,然后根据 key 在内存 index 中进行一个二分查找,查到该 key 对应的磁盘的 offset 后,去磁盘把响应的块数据读取出来。

在这里插入图片描述

MemTable 达到一定大小会被 flush 到硬盘中变成 SSTable。在不同的 SSTable 中可能存在相同的 Key 记录。但这样会带来一些问题:

  • 冗余存储。对于某个 Key,除了最新的记录,其他记录都是冗余无用的。所以我们需要进行 Compact 操作(合并多个 SSTable),来清除冗余的记录。
  • 读取时需要从最新的 SSTable 出发进行查询,最坏情况下药查询完所有的 SSTable。可以通过索引或布隆过滤器来优化查找速度。
LSM-Tree读写数据
LSM-Tree写数据流程
  • WAL当收到写请求,先将数据记录在 WAL Log 中,用作故障恢复。把操作同步到磁盘中WAL做备份(追加写、性能极高)

  • Memtable完成WAL后将(k,v)数据写入内存中的Memtable,Memtable的数据结构一般是跳表或者红黑树

    内存内采用这种数据结构一方面支持内存内高速增删改查(时间复杂度O(logM)),另一方面可以保持有序,为写入磁盘中的SSTable打基础

    • 如果是删除,则做墓碑标记
    • 如果是更新,则新记录一条数据
  • Immutable Memtable

    • MemTable 达到一定大小后,在内存中冻结,成为不可变的 ImmuTable MemTable。同时也要生成新的 MemTable 来提供服务。
  • **Minor Compaction ** SSTable的数据结构是LSM-Tree设计的精髓,他一方面可以保持有序,一方面又能利用磁盘追加写的高性能。

    • 内存中不可变的 MemTable 被 dump 到硬盘上的 SSTable 中,这也称为 **Minor Compaction。**注意 L0 层的 SSTable 是没有合并的,所以 key 在多个 SSTable 中往往会重叠、冗余。
    • 当每层 SSTable 超过一定大小,就会周期性的进行合并,这也称为 Major Compaction。这个阶段回清除掉荣誉的数据,防止浪费空间。由于 SSTable 都是有序的,可以使用归并排序进行高效合并。

Major Compaction merge

当level 0中的segment越来越多,查询需要遍历的segment也就会越来越多,并且随着时间的推移,重复的key也会越来越多,在后面的步骤就需要对level 0层的segment进行合并merge。

合并的过程中是吧多个有序的segment进行归并合并,所以性能不会很差,多个老的segment会合并成一个更长的同样有序的segment并设置到下一层每一层的segment的数量和大小都会有限制,每当超出限制后,就会做合并操作。

  • 虽然定期合并可以有效的清除无效数据,缩短读取路径提升查询效率,提高磁盘利用空间。但Compaction操作是非常消耗CPU和磁盘IO的,尤其是在业务高峰期,如果发生了Major Compaction,则会降低整个系统的吞吐量,这也是一些NoSQL数据库,比如Hbase里面常常会禁用Major Compaction,并在凌晨业务低峰期进行合并的原因。
LSM-Tree读数据流程
  • 当收到读请求,现在内存中查询,查询到就返回。
  • 如果没有查询到,由内存到磁盘,在各级 SSTable 中依次下沉,直到得到结果
    • 按照Memtable(内存)、Immutable Memtable(内存)、level 0 segments(磁盘)、level 1 segments(磁盘)、level 1 segments(磁盘)的顺序查询
    • 每层先查新生成的segment,每个segment从后向前查。
LSM-Tree的Compact策略

Compact 是 LSM 树中的关键操作,只有 Compact 的策略合理,才能及时有效地清除冗余的数据。介绍以下几个概念:

  • **读放大。**读取数据时实际读取的数据量大于真正的数据量。例如在不同层次的 Table 中查找。
  • **写放大。**写入数据时实际写入的数据量大于真正的数据量。例如写入时触发 Compact,导致写入大量数据。
  • **空间放大。**数据占用的磁盘空间比真正的数据大小要大很多。即冗余存储。
size-tiered策略

size-tiered 策略保证每层中每个 SSTable 的大小相近,同时限制每一层 SSTable 的数量。

每层限制有 N 个 SSTable,每层数量达到 N 后,触发 Compact 操作来合并这些 SSTable,放入下一层成为更大的 SSTable。

当层数越来越大,单个 SSTable 的大小也会越来越大。该策略会导致空间放大比较严重。对每一层的 SSTable 来说,每个 key 的记录也可能存在多份。只有该层执行 Compact 操作才会消除这些冗余记录。

leveled策略

leveled 策略限制每一层总文件的大小。

**leveld 同样将每一层划分为大小相近的 SSTable。并保证在一层内全局有序。**这意味着与一个 Key 在每一层至多只有一条记录,不存在冗余记录。

leveled 策略相比 size-tiered 策略来说,每层内的 Key 是有序、不重复的。这样就很好地控制了冗余 Key 的量。

查询优化

查询过程中我们发现,在原始情况下,我们需要遍历所有的 SSTable。我们考虑以下方式,尝试优化查询的效率。

  • **压缩。**SSTable可以进行压缩,而且不是压缩整个 SSTable。而是根据局部性原理将数据分组。每个分组分别压缩。这样读取数据的时候我们就不需要解压缩整个文件,而是解压缩部分 Group 即可读取。
  • **缓存。**SSTable 除了进行 Compaction,其他情况下是不可变的。所以我们可以将一次扫描到的 Block 进行缓存,提高下一次检索的效率。
  • **索引/布隆过滤器。**正常情况下,一次读操作需要读取所有 SSTable,再将结果合并后返回。但是对某些 Key 而言,有些 SSTable 根本不包含对应数据。所以我们可以为每个 SSTable 添加布隆过滤器。来判断当前 SSTable 有没有我们需要的 Key。
  • **合并。**合并本身肯定可以优化数据的组织情况,提高查询效率。但是也要注意查询是非常消耗 CPU 和磁盘 IO 的操作。一般我们选在业务量不大的凌晨等情况进行合并。
为什么LSM不直接顺序写入磁盘,而是需要在内存中缓冲一下

单条写的性能没有批量写快,很多中间件比如elasticsearch、kafka、mysql都有类似的内存缓冲设计

在磁盘缓冲的另一个好处是,针对新增的数据,可以直接查询返回,能够避免一定的IO操作

LSM-Tree和B+Tree的比较
  • LSM-Tree的优点是支持高吞吐的写O1,这个特点在分布式系统上更为看重针对读取普通的LSM-Tree结构,读取是On的复杂度在使用索引或者缓存优化后的也可以达到O(logN)的复杂度。适用于写多读少

  • B+tree的优点是支持高效的读(稳定的O(logN))但是在大规模的写请求下(O(LogN)),效率会变得比较低,因为随着insert的操作,为了维护B+树结构,节点会不断的分裂和合并。操作磁盘的随机读写概率会变大,故导致性能降低。适用于写少读多或写读平衡

  • LSM-Tree 的写放大问题比 B-Tree 要好一些。因为 B 树写入的页分裂操作实在太消耗磁盘 IO。

  • LSM-Tree 可以支持更好的压缩。由于碎片,B-Tree 无法使用某些磁盘空间,而 LSM-Tree 会定期重写来消除碎片。

  • LSM_Tree 在执行压缩操作时,很容易发生读写请求等待的问题。而 B-Tree 的响应延迟则更具确定性。

  • B-Tree 中的每个键都位于索引中的每个位置,而日志结构的存储引擎可能在不同的段中有相同键的多个副本。如果数据库希望提供严格的事务语义,B-Tree 要更容易实现一些,因为锁可以定义到树中。

  • LSM_Tree 在执行压缩操作时,很容易发生读写请求等待的问题。而 B-Tree 的响应延迟则更具确定性。

  • B-Tree 中的每个键都位于索引中的每个位置,而日志结构的存储引擎可能在不同的段中有相同键的多个副本。如果数据库希望提供严格的事务语义,B-Tree 要更容易实现一些,因为锁可以定义到树中。

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

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

相关文章

newtonsoft.json动态读取json以及动态生成

问题 同一个接口返回不同类型的json&#xff0c;json结构相差比较大转换为C#对象不太合适&#xff0c;想着是否可以动态解析。 newtonsoft类 JTokenType类型 namespace Newtonsoft.Json.Linq {/// <summary>/// Specifies the type of token./// </summary>publ…

快速学习 JavaFX 进行 GUI 应用开发

JavaFX是Java的一个用于构建丰富图形用户界面的框架。通过JavaFX&#xff0c;开发者可以创建功能强大、交互性强且美观的桌面应用程序。 一、JavaFX简介 1. JavaFX的历史和现状 JavaFX最初作为Java的一部分发布&#xff0c;旨在替代Swing作为Java的主要GUI工具包。JavaFX提供…

uni-app中使用富文本rich-text个人经验

rich-text是在uni-app一个内置组件&#xff0c;用于高性能地渲染富文本内容。先贴一下官方的属性列表&#xff1a; 先说一下“selectable” 长按选择区域复制&#xff0c;这个我在APP项目中 不起作用&#xff0c;可能像文档说的&#xff0c;只支持“百度小程序”吧。在APP端起作…

为数据安全护航,袋鼠云在数据分类分级上的探索实践

在大数据时代&#xff0c;数据具有多源异构的特性&#xff0c;且价值各异&#xff0c;企业需依据数据的重要性、价值指数等予以区分&#xff0c;以利采取不同的数据保护举措&#xff0c;避免数据泄露。故而&#xff0c;数据分类分级管理属于数据安全保护中极为重要的环节之一。…

正则表达式写起来不简单,但用起来真香

说在前面 &#x1f388;整理一些常见常用的正则表达式。 常见的正则表达式 1、手机号码 /^[1][3456789][0-9]{9}$/这个正则表达式 /^[1][3456789][0-9]{9}$/ 用于匹配中国的手机号码的一部分&#xff0c;但不包括全部有效的手机号码格式。下面是对它的详细解释&#xff1a; ^…

项目三OpenStack基础环境配置与API使用

任务一 了解OpenStack基础环境配置 1.1 •数据库服务器 1.2 •消息队列服务 •AMQP系统的组成 任务二 了解并使用OpenStack API 2.1 •什么是RESTful API • RESTful API 是目前比较成熟的 一套Internet应用程序的API软件架构 。 • 表现 层&#xff08; Representation …

JavaWeb项目配置教程

将你的项目&#xff08;只有代码的文件&#xff0c;不是整个文件&#xff09;拖入idea 找到数据库配置代码&#xff08;一般在Util包里面&#xff0c;或者是properties配置文件&#xff09;并将密码修改为你的数据库密码。 点击Edit Configurations 点击Configure&#xff0…

突破数据存储瓶颈!转转业财系统亿级数据存储优化实践--图文解析

突破数据存储瓶颈&#xff01;转转业财系统亿级数据存储优化实践–图文解析 原文链接&#xff1a;https://juejin.cn/post/7358704806779437097 原文作者&#xff1a;转转技术团队 业财系统&#xff1a;业务和财务一体化系统 与传统财务记账不同&#xff0c;一笔金额不再是…

LED电子看板在提升企业数字化管理的应用价值

本文详细探讨 LED 电子看板在企业数字化管理中的应用价值&#xff0c;包括实时数据展示、可视化管理、提高生产效率、优化决策等方面&#xff0c;通过实际案例分析&#xff0c;阐述了其对企业发展的重要性。在当今数字化时代&#xff0c;企业管理面临着越来越多的挑战和机遇。为…

企业IT资源使用共享云桌面集中管理的优势

随着信息技术的飞速发展&#xff0c;企业面临着日益增长的IT资源需求和管理挑战。为了解决这一问题&#xff0c;越来越多的企业开始采用云桌面集中管理方案&#xff0c;以实现IT资源的共享和优化。 为保持企业各部门信息化和数字化业务顺利运转&#xff0c;IT需要耗费大量支持…

【BFS算法】广度搜索·由起点开始逐层向周围扩散求得最短路径(算法框架+题目)

0、前言 深度优先搜索是DFS&#xff08;Depth Frst Search)&#xff0c;其实就是前面所讲过的回溯算法&#xff0c;它的特点和它的名字一样&#xff0c;首先在一条路径上不断往下&#xff08;深度&#xff09;遍历&#xff0c;获得答案之后再返回&#xff0c;再继续往下遍历。…

使用SQLite

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 与许多其他数据库管理系统不同&#xff0c;SQLite不是一个客户端/服务器结构的数据库引擎&#xff0c;而是一种嵌入式数据库&#xff0c;它的数据库就…

微量氧传感器在3D打印中的应用

3D打印为什么需要监测氧气&#xff1f; 金属 3D 打印过程涉及使用激光技术将细金属粉末一层一层地熔合在一起。在制造零件的同时将杂质风险降至比较低是金属增材制造行业面临的主要挑战。金属 3D 打印机通常将其原料送入惰性环境中&#xff0c;以消除污染并防止质量问题。氩气…

【自撰写】【国际象棋入门】第6课 常见术语分析(一)吃双和抽将

第6课 常见术语分析&#xff08;一&#xff09;吃双和抽将 本次课中&#xff0c;我们介绍几种最为常见和常用的&#xff08;单步棋形成&#xff09;的局面、术语并对其进行简单的分析。一般说来&#xff0c;这些局面都会给予一方以“立竿见影”的优势&#xff0c;或者引向之后…

瑞尼克定制聚四氟乙烯布氏漏斗配抽滤瓶四氟抽滤装置药厂

一、产品介绍 布氏漏斗是实验室中使用的一种仪器&#xff0c;用来使用真空或负压力抽吸进行过滤。布氏漏斗可代替陶瓷布氏漏斗&#xff0c;避免碎裂&#xff0c;聚四氟乙烯材质的布氏漏斗性强&#xff0c;使用真空或负压力抽吸进行过滤也可与吸滤瓶配套&#xff0c;用于无机制…

window 卸载应用商店程序

# 使用Get-AppxPackage获取所有应用程序 # 使用Remove-AppxPackage PythonSoftwareFoundation.Python.3.12_3.12.1264.0_x64__qbz5n2kfra8p0

2024请收好这一份全面--详细的AI产品经理从业指南

前言 入行人工智能领域这段时间以来&#xff0c;从零到一把AI推荐系统产品化搭建了起来&#xff0c;也与很多同行AI产品经理小伙伴建立了联系。AI产品经理工作内容各异&#xff0c;不同AI产品化生命周期中更是大为不同&#xff0c;但对想入行AI产品经理的小伙伴来讲&#xff0…

聊一聊生成式AI

生成式AI&#xff08;Generative AI&#xff09;是指一类能够自主创造新内容的人工智能技术&#xff0c;这些内容可以是文本、图像、音频、视频等。与传统的分析性或分类性AI系统不同&#xff0c;生成式模型的主要任务不是对现有数据进行分类或预测&#xff0c;而是生成全新的、…

【C语言 || 排序】希尔排序

文章目录 前言1.希尔排序1.1 直接插入排序1.2 直接插入排序的实现1.2.1 直接插入排序的代码实现 1.3 直接插入排序的时间复杂度1.4 希尔排序1.4.1 希尔排序概念1.4.1 希尔排序的代码实现 前言 1.希尔排序 1.1 直接插入排序 在写希尔排序之前&#xff0c;我们需要先了解直接插入…

电压模式R-2R DAC的工作原理和特性

本文将探讨电压模式R-2R DAC结构。 在本文中&#xff0c;我们将探索什么是R-2R DAC以及如何实现它们。 首先&#xff0c;我们将简要回顾一下开尔文分压器DAC。这种结构很简单&#xff0c;但它们需要大量的电阻和开关来实现高分辨率DAC。这个问题的一个解决方案是称为R-2R DAC…