【博客719】时序数据库基石:LSM Tree的增删查改

embedded/2024/10/22 14:36:09/

数据库>时序数据库基石:LSM Tree的增删查改

LSM结构

LSM树将任何的对数据操作都转化为对内存中的Memtable的一次插入。Memtable可以使用任意内存数据结构,如HashTable,B+Tree,SkipList等。对于有事务控制需要的存储系统,需要在将数据写入Memtable之前,先将数据写入持久化存储的WAL(Write Ahead Log)日志。由于WAL日志是顺序Append到持久化存储的,因此无论对磁盘还是SSD都是非常友好的。
在这里插入图片描述

LSM树各类操作

前面我们提到了LSM的结构和合并,现在来看下LSM结构的增删查改:

再强调一次下面的概念:

  • LSM树的增加、删除、修改(这三个都属于写操作)都是在内存中倒腾,完全没涉及到磁盘操作。当要修改现有数据时,LSM Tree并不直接修改旧数据,而是直接将新数据写入新的SSTable中。同样的,删除数据时,LSM Tree也不直接删除旧数据,而是写一个相应数据的删除标记的记录到一个新的SSTable中
  • LSM Tree写数据时对磁盘的操作都是顺序块写入操作,而没有随机写操作。
  • LSM Tree这种独特的写入方式,导致在查找数据时,LSM Tree就不能像B+树那样在一个统一的索引表中进行查找,而是从最新的SSTable到老的SSTable依次进行查找。如果在新SSTable中找到了需查找的数据或相应的删除标记,则直接返回查找结果;如果没有找到,再到老的SSTable中进行查找,直到最老的SSTable查找完
  • 为了提高查找效率,LSM Tree对SSTable进行分层、有序组织,也就是说把SSTable组织成多层,同一层可以有多个SSTable,同一个数据在同一层的多个SSTable中可以不重复,而且数据可以做到在同一层中是有序的,即每一个SSTable内的数据是有序的,前一个SSTable的最大数据值小于后一个SSTable的最小数据值(实际情况比这个复杂,后面会介绍)。这样可以加快在同一层SSTable中的数据查询速度。同时,LSM Tree会将多个SSTable合并(Compact)为一个新的SSTable,这样可以减少SSTable的数量,同时把修改前的数据或删除的数据真正从SSTable中删除,减小了SSTable的大小(这就是Log-Structured Merge Tree名字中Merge一词的由来),对提高查找性能极其重要
  • LSM树将任何的对数据操作都转化为对内存中的Memtable的一次插入
  • Memtable可以使用任意内存数据结构,如HashTable,B+Tree,SkipList
  • 对于有事务控制需要的存储系统,需要在将数据写入Memtable之前,先将数据写入持久化存储的WAL(Write Ahead Log)日志。由于WAL日志是顺序Append到持久化存储的,因此无论对磁盘还是SSD都是非常友好的。

小话题:加入了WAL的结构如下在这里插入图片描述

LSM树支持常见的变更操作,插入,删除,更新。常见的实现里,为了统一变更的数据结构标识,往MemTable里写入的除了<Key, TimeStamp, Value>三元组外,还会带上操作的类型。所有的变更操作并不直接修改磁盘上的数据,而只是将变更写入MemTable。因此数据变更除了WAL日志一次顺序IO之外,没有额外的任何随机IO,插入效率非常高。

1、数据写入

无WAL的写入:

由于 LSM tree 只会进行顺序写入,所以自然而然地就会引出这样一个问题,写入的数据可能是任意顺序的,我们又如何保证数据能够保持 SSTable 要求的有序组织呢?
这就需要引入新的常驻内存 (in-memory) 数据结构: memtable_了, _memtable 的底层数据结构可以是类似红黑树这种,当有新的写入操作则将数据插入到红黑树中。

写入操作会先把数据存储到红黑树中,直至红黑树的大小达到了预先定义的大小。一旦红黑树的大小达到阈值,就会把数据整个刷到磁盘中,这个过程就可以把数据保证有序写入了。经过一层数据结构的承接,就可以保证单向顺序写入的同时,也能保证数据的有序。

在这里插入图片描述

注意:如果是有WAL的写入,则是以下操作

  • 当收到一个写请求时,会先把该条数据记录在WAL Log里面,用作故障恢复。

  • 当写完WAL Log后,会把该条数据写入内存的SSTable里面(删除是墓碑标记,更新是新记录一条的数据),也称Memtable。注意为了维持有序性在内存里面可以采用红黑树或者跳跃表相关的数据结构。

  • 当Memtable超过一定的大小后,会在内存里面冻结,变成不可变的Memtable,同时为了不阻塞写操作需要新生成一个Memtable继续提供服务。

  • 把内存里面不可变的Memtable给dump到到硬盘上的SSTable层中,此步骤也称为Minor Compaction,这里需要注意在L0层的SSTable是没有进行合并的,所以这里的key range在多个SSTable中可能会出现重叠,在层数大于0层之后的SSTable,不存在重叠key。

  • 当每层的磁盘上的SSTable的体积超过一定的大小或者个数,也会周期的进行合并。此步骤也称为Major Compaction,这个阶段会真正 的清除掉被标记删除掉的数据以及多版本数据的合并,避免浪费空间,注意由于SSTable都是有序的,我们可以直接采用merge sort进行高效合并。

2、数据变更

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、数据删除

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、数据查找

  • 根据LSM Tree的写入特点我们知道,如果一项数据更新多次,这项数据可能会存储在多个不同的SSTable中,甚至一项数据的不同部分的最新数据内容存储在不同的SSTable中(数据部分更新的场景)。LSM Tree把这种现象叫做空间放大(space amplification),因为一项数据在磁盘中存储了多份副本,而老的副本是已经过时了的,不需要的,数据实际占用的存储空间比有效数据需要的大。

  • 空间放大这种现象导致LSM Tree的查找过程是这样的:按新到老的顺序查找SSTable,直到在某个(或某些个)SSTable中查找到了所需的数据,或者最老的SSTable查找完也没有找到需要的数据。具体查找顺序为:先在内存MemTable中查找,然后在内存中的Immutable MemTable中查找,然后在level 0 SSTable中查找,最后在level N SSTable中查找。

  • 查找某个具体的SSTable时,一般先把SSTable的元数据block读到内存中,根据BloomFilter可以快速确定数据在当前SSTable中是否存在,如果存在,则采用二分法确定数据在哪个数据block,然后将相应数据block读到内存中进行精确查找。

  • 从LSM Tree数据查找过程我们可以看到,为了查找到目标数据,我们需要读取并查找不包含目标数据的SSTable,如果目标数据在最底层level N的SSTable中,我们需要读取和查找所有的SSTable!LSM Tree把这种读取和查找了无关SSTable的现象叫做读放大(read amplification)。

点查:

范围查询

范围查询根据表的查询Key的范围区间[StartKey, EndKey],通常会先对StartKey在LSM树上逐层做LowerBound查询,即每一层上找到大于或等于StartKey的数据的起始位置。由于LSM树每一层都是有序的(内存中的MemTable如果是无序的Hash表则需要全部遍历),只需要从这个起始位置开始读取数据,直到读取到EndKey为止。

5、数据合并

在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/embedded/51216.html

相关文章

如何验证Rust中的字符串变量在超出作用域时自动释放内存?

讲动人的故事,写懂人的代码 在公司内部的Rust培训课上,讲师贾克强比较了 Rust、Java 和 C++ 三种编程语言在变量越过作用域时自动释放堆内存的不同特性。 Rust 通过所有权系统和借用检查,实现了内存安全和自动管理,从而避免了大部分内存泄漏。Rust 自动管理标准库中数据类…

Oracle 入门--前提

目录 1.sqlplus 2.dual是什么&#xff1f; 3.SQL语句的种类 4.Oracle是如何工作的 5.Oracle查看配置文件 6.修改配置文件 7.常用的参数设置 1.sqlplus 管理数据库&#xff1a;启动&#xff0c;关闭&#xff0c;创建&#xff0c;删除对象......查看数据库的运行状态&…

【小程序】WXSS模板样式

目录 WXSS模板样式 概述 什么是WXSS WXSS 和 CSS 的关系 rpx 什么是rpx尺寸单位 rpx的实现原理 样式导入 import 语法格式 全局样式和局部样式 全局样式 局部样式 全局配置 全局配置文件及常用的配置项 window 小程序窗口的组成部分 window节点常用的配置项…

中学理化生实验室建设及配置要求

在中学物理、化学、生物等学科教学中&#xff0c;实验占据了非常重要的地位&#xff0c;是整个教学过程中不可或缺的部分。很多理科教学需要在实验室完成演示和学习任务&#xff0c;实验室也是保证教学计划得以实施的物质基础。因此&#xff0c;中学理化生实验室建设标准与否&a…

echarts地图修改图例

要求&#xff1a;根据数据排名&#xff0c;前三名点亮橙色&#xff0c;其他地区根据数值分配不同颜色&#xff0c;并且要加上单位 效果图如下&#xff1a; 实现方法如下&#xff1a; visualMapFormat(list) {//先将数据按从大到小的顺序排列//当list长度为1时&#xff0c;点亮…

html做一个雷达图的软件

要实现一个在线输入数据并生成雷达图的功能&#xff0c;可以使用HTML表单和JavaScript来处理用户输入的数据。以下是一个示例代码&#xff0c;演示了如何实现这个功能&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"…

android 对不同日期和时间的格式方法的封装

break; default: result “星期一”; break; } return result; } /** 判断两个时间是否属于同一天 param time1 param time2 return */ public boolean isSameDay(long time1, long time2) { Calendar calen Calendar.getInstance(); calen.setTimeInMillis(t…

力扣42.接雨水

力扣42.接雨水 前后缀数组 对于每个一个位置 求其前面最高高度pre_max[i] max(pre_max[i-1] , h[i])和后面最高高度suf_max[i] max(suf_max[i1] , h[i])当前i处的水容量 为min(pre_max[i] , suf_max[i]) - h[i] class Solution {public:int trap(vector<int>& …