【LSM tree 】Log-structured merge-tree 一种分层、有序、面向磁盘的数据结构
文章目录
- 前言
- 基本原理
- 读写流程
- 写流程
- 读流程
- 写放大、读放大和空间放大
- 优化
前言
LSM Tree 全称是Log-structured merge-tree, 是一种分层,有序,面向磁盘的数据结构。其核心原理是磁盘批量顺序写比随机写性能高很多,可以通过围绕这一原理进行设计和优化,让写性能达到最优。相较于传统的B+树,它减少了磁盘随机读取的需求,从而在一定程度上改善了数据库的写能力,当然在一定程度上牺牲了数据库的读能力。LSM tree也是当今流行的各种NoSQL或NewSQL数据库最基础的底层数据结构,广泛使用在包括Hbase,Cassandra,Leveldb, RocksDB, TiDB等项目中。
基本原理
传统的B+树的缺陷就是在访问节点时涉及到了大量的磁盘随机读写,因为你无法保证节点常驻内存,尤其是当B+树管理的索引量很大的时候,这导致数据库读写性能急剧下降。
LSM tree 采取的做法就是通过引入多部件索引来减少磁盘随机读写的需求。在大量插入情况下我们周期性地选取两部分索引进行合并,并且把合并后的有序文件(或内存块)添加到磁盘尾部(或成为新文件),修改节点信息以保证索引树的正确和完善,并且周期性地回收失效索引。因此与其说LSM tree是一种树,不如说它是通过传统索引组织有序文件或内存块的一种方式。
LSM tree的节点可以分为两种:
- MemTable: 保存在内存中的部分,一般可以是红黑树、跳跃表,甚至可以是B树。在HBase中使用的是跳表,在SQLite4中使用的是只能追加写入的红黑树。
- SSTable: 保存在磁盘上的部分,一般由多个内部KeyValue有序的文件组成,它的key和value都是任意的字节数组,并且了提供了按指定key查找和指定范围dekey区间迭代遍历的功能。SSTable内部包含了系列可匹配大小的Block块。关于这些Block块的index存储在SSTable的尾部,用于帮助快速查找。
写操作直接作用于MemTable,因此写入性能接近写内存。每层SSTable文件到达一定条件后,进行合并操作,然后放置到更高层。合并操作在实现上一般的策略驱动、可插件化的。
读写流程
写流程
- 当收到一个写请求时,会先把该条数据记录在 WAL(Write-ahead logging)里面,用作故障恢复。
- 当写完 WAL 后,会把该条数据写入内存的 MemTable 里面(删除操作也通过写入实现,会写入一个删除标记;更新则是写入一条新记录)。
- 当 Memtable 超过一定的大小后,会在内存里面冻结,变成不可变的 Memtable,同时为了不阻塞写操作需要新生成一个 Memtable 继续提供服务。
- 把内存里面不可变的 Memtable 给 flush 到到硬盘上的 SSTable 层中,此步骤也称为 Minor Compaction,这里需要注意在 L0 层的 SSTable 是没有进行合并的,所以这里的 key range 在多个 SSTable 中可能会出现重叠,在层数大于 0 层之后的 SSTable,不存在重叠 key。
- 当每层的磁盘上的 SSTable 的体积超过一定的大小或者个数,也会周期的进行合并。此步骤也称为 Major Compaction。这个阶段会真正的清除掉被标记删除掉的数据以及多版本数据的合并,避免浪费空间,注意由于 SSTable 都是有序的,我们可以直接采用 merge sort 进行高效合并。
读流程
- 当收到一个读请求的时候,会直接先在内存里面查询,如果查询到就返回。
- 内存查询包括服务中的 Memtable 和不可变的 Memtable,也包括对于 SSTable 的缓存 block cache。
- 如果内存中没有查询到就会依次下沉查询 SSTable,直到把所有的层次的 SSTable 查询一遍得到最终结果。
写放大、读放大和空间放大
LSM Tree 将随机写转化为顺序写,而作为代价带来了大量的重复写入。由此会引起写放大、读放大和空间放大。
- 写放大(Write Amplification):
平均写入 1 个字节,引擎中在数据的声明周期内实际会写入 n 个字节,其写放大率是 n。如果业务方写入速度是 10MB/s,在引擎端或者操作系统层面能观察到的数据写入速度是 30MB/s,系统的写放大率就是 3。写放大过大会制约系统的实际吞吐。对于 SSD 来说,也会导致 SSD 寿命缩短。
以下是 HBase 中的写放大示意图
- 读放大(Read Amplification):
一个读请求,系统所需要读 n 个页面来完成查询,其读放大率是 n。逻辑上的读操作可能会命中引擎内部的 cache 或者文件系统 cache,命中不了 cache 就会进行实际的磁盘 IO,命中 cache 的读取操作的代价虽然很低,但是也会消耗 CPU。
以下是 HBase 中的读放大示意图
- 空间放大(Space Amplification):
平均存储 1 个字节的数据,在存储引擎内部所占用的磁盘空间 n 个字节,其空间放大是 n。比如写入 10MB 的数据,磁盘上实际占用了 100MB,这是空间放大率就是 10。空间放大和写放大在调优的时候往往是排斥的,空间放大越大,那么数据可能不需要频繁的 compaction,其写放大就会降低;如果空间放大率设置的小,那么数据就需要频繁的 compaction 来释放存储空间,导致写放大增大
优化
LSM tree 一般从以下几个方面进行优化:
- 压缩
SSTable 是可以启用压缩功能的,并且这种压缩不是将整个 SSTable 一起压缩,而是根据 locality 将数据分组,每个组分别压缩,这样的好处当读取数据的时候,我们不需要解压缩整个文件而是解压缩部分 Group 就可以读取。
- 缓存
因为 SSTable 在写入磁盘后,除了 Compaction 之外,是不会变化的,所以我可以将 Scan 的 Block 进行缓存,从而提高检索的效率。
- Bloom filter
正常情况下,一个读操作是需要读取所有的 SSTable 将结果合并后返回的,但是对于某些 key 而言,有些 SSTable 是根本不包含对应数据的,因此,我们可以对每一个 SSTable 添加 Bloom Filter,因为 Bloom Filter 在判断一个 SSTable 不存在某个 key 的时候,那么就一定不会存在,利用这个特性可以减少不必要的磁盘扫描。
- 合并
通过定期合并瘦身, 可以有效的清除无效数据,缩短读取路径,提高磁盘利用空间。但 Compaction 操作是非常消耗 CPU 和磁盘 IO 的,尤其是在业务高峰期,如果发生了 Major Compaction,则会降低整个系统的吞吐量,这也是在使用一些 NoSQL 数据库时,比如 Hbase,常常会禁用 Major Compaction,并在凌晨业务低峰期进行合并的原因。
ref:https://popesaga.github.io/2020/09/25/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%EF%BC%9ALSM%20tree/#%E5%86%99%E6%94%BE%E5%A4%A7%E3%80%81%E8%AF%BB%E6%94%BE%E5%A4%A7%E5%92%8C%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7
相关文章:

【LSM tree 】Log-structured merge-tree 一种分层、有序、面向磁盘的数据结构
文章目录 前言基本原理读写流程写流程读流程 写放大、读放大和空间放大优化 前言 LSM Tree 全称是Log-structured merge-tree, 是一种分层,有序,面向磁盘的数据结构。其核心原理是磁盘批量顺序写比随机写性能高很多,可以通过围绕这一原理进行…...

配置OSPF与BFD联动示例
定义 双向转发检测BFD(Bidirectional Forwarding Detection)是一种用于检测转发引擎之间通信故障的检测机制。 BFD对两个系统间的、同一路径上的同一种数据协议的连通性进行检测,这条路径可以是物理链路或逻辑链路,包括隧道。 …...
01到底应该怎么理解“平均负载”
1、如何了解系统的负载情况? 每次发现系统变慢时, 我们通常做的第⼀件事, 就是执⾏top或者uptime命令, 来了解系统的负载情况。 ⽐如像下⾯这样, 我在命令⾏⾥输⼊了uptime命令, 系统也随即给出了结果。 …...

jmeter,动态参数之随机数、随机日期
通过函数助手,执行以下配置: 执行后的结果树: 数据库中也成功添加了数据,对应字段是随机值:...
uniApp常见知识点-问题答案
1、uniApp中如何进行页面跳转? 答案:可以使用 uni.navigateTo、uni.redirectTo 和 uni.reLaunch 等方法进行页面跳转。其中,uni.navigateTo可以实现页面的普通跳转, uni.redirectTo可以实现页面的重定向跳转, uni.reL…...

云原生基础入门概念
文章目录 发现宝藏云原生的概念云原生的关键技术为何选择云原生?云原生的实际应用好书推荐 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 云原生的概念 当谈及现…...

一个 tomcat 下如何部署多个项目?附详细步骤
一个tomcat下如何部署多个项目?Linux跟windows系统下的步骤都差不多,以下linux系统下部署为例。windows系统下部署同理。 1 不修改端口,部署多个项目 清楚tomcat目录结构的应该都知道,项目包是放在webapps目录下的,那…...

pycharm强制让terminal停止执行的快捷键
CtrlC即可...
MFC(Microsoft Foundation Classes)中 MessageBox
在MFC(Microsoft Foundation Classes)中,MessageBox是一个常用的对话框类,用于显示消息框并与用户进行交互。MessageBox类提供了多种用法和选项,以下是一些常见的用法和示例说明: 显示简单的消息框&#x…...

如何让.NET应用使用更大的内存
我一直在思考为何Redis这种应用就能独占那么大的内存空间而我开发的应用为何只有4GB大小左右,在此基础上也问了一些大佬,最终还是验证下自己的猜测。 操作系统限制 主要为32位操作系统和64位操作系统。 每个进程自身还分为了用户进程空间和内核进程空…...

【从零开始学习JVM | 第九篇】了解 常见垃圾回收器
前言: 垃圾回收器(Garbage Collector)是现代编程语言中的一项重要技术,它提供了自动内存管理的机制,极大地简化了开发人员对内存分配和释放的繁琐工作。通过垃圾回收器,我们能够更高效地利用计算机的内存资…...

Wordle 游戏实现 - 使用 C++ Qt
标题:Wordle 游戏实现 - 使用 C Qt 摘要: Wordle 是一款文字猜词游戏,玩家需要根据给定的单词猜出正确的答案,并在限定的次数内完成。本文介绍了使用 C 和 Qt 框架实现 Wordle 游戏的基本思路和部分代码示例。 引言:…...

Python 爬虫开发完整环境部署,爬虫核心框架安装
Python 爬虫开发完整环境部署 前言: 关于本篇笔记,参考书籍为 《Python 爬虫开发实战3 》 笔记做出来的一方原因是为了自己对 Python 爬虫加深认知,一方面也想为大家解决在爬虫技术区的一些问题,本篇文章所使用的环境为&#x…...

汽车标定技术(十三)--标定概念再详解
目录 1.概述 2.基于Flash的标定 3.基于RAM的标定 4.AUTOSAR基于指针标定概念 5.小结 1.概述 最近有朋友问到是否用overlay标定完数据就直接写在Flash中,其实不然,是需要关闭overlay然后通过XCP Program指令集或者UDS刷进Flash。 从这里看出&#…...

PostgreSQL常用命令
数据库版本 :9.6.6 注意 :PostgreSQL中的不同类型的权限有 SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER,CREATE,CONNECT,TEMPORARY,EXECUTE 和 USAGE。 1. 登录PG数据库 以管理员身份 postgres 登陆,然后通过 #psql -U postgres #sudo -i -u postgres …...
使用python脚本部署k8s集群
1.环境规划: 节点IP地址操作系统配置脚本运行节点192.168.174.5centos7.92G2核server192.168.174.150centos7.92G2核client1192.168.174.151centos7.92G2核client2192.168.174.152centos7.92G2 2.运行准备: yum install -y python python-pip pip in…...

【C语言】操作符详解(四):结构成员访问操作符
目录 结构成员访问操作符 结构体 结构体的声明 结构体变量的定义和初始化 结构成员访问操作符 结构体成员的直接访问 结构体成员的间接访问 结构成员访问操作符 结构体 ⭐C语言已经提供了内置类型,如: char、short、int、long、float、double等,但…...

【算法】二分法
1、二分法 1.1 二分法原理 每次将查找的范围缩小一半,直到最后找到记录或者找不到记录返回。 要求:采用二分法查找时,数据需是排好序的。 1.2二分法思路 判断某个数是否在数组中存在(例:判断3是否在数组中存在&#…...
2023.12.18 JAVA学习day03,while与for循环
目录 0.switch 判断语句 一.for循环 1.简单练习 2.使用for循环计算1-100求和, 以及偶数求和 3.进阶练习,配合键盘录入与判断使用循环 二.while循环 三种格式的区别: 0.switch 判断语句 switch (表达式) { case 1: 语句体1; break; case …...

使用Pytorch从零开始构建StyleGAN2
这篇博文是关于 StyleGAN2 的,来自论文Analyzing and Improving the Image Quality of StyleGAN,我们将使用 PyTorch 对其进行干净、简单且可读的实现,并尝试尽可能地还原原始论文。 如果您没有阅读 StyleGAN2 论文。或者不知道它是如何工作…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...