当前位置: 首页 > news >正文

数据库管理-第127期 LSM Tree(202301225)

数据库管理-第127期 LSM Tree(202301225)

说起分布式数据库,绕不开的一个话题就是LSM Tree,全称为log-structured merge-tree,回到吕海波老师授权过的那句话“没搞过Oracle的,但又是数据库圈里的人,特别做数据库开发的,对Oracle的印象就是:集中式、落后、旧时代的产物,超过Oracle很简单,基于Poxos/Raft,随便上个分布式就可以了。如果再实现个LSM Tree,那就超过Oracle太多了。”可见LSM Tree对于分布式数据库是很重要的一个东西,无论是国外的HBase、Cassandra、LevelDB、RocksDB等,还是国内较为出名的OceanBase、TiDB等,都是使用LSM Tree来组织数据。

1 基本

LSM Tree和B+ Tree是数据库创建block(块)的时候提到的两种基础数据结构。B+ Tree一般用于较少查询和插入时间的场景,而LSM Tree则用于写压力非常大而读要求不是那么高的场景。
LSM Tree并非是一个所谓的新技术,从维基百科来看这是一个诞生于1996年的技术,较早发表用于具体技术则是2006年Google发表的论文《Bigtable: A Distributed Storage System for Structured Data》,这篇论文也被誉为分布式数据库开山鼻祖之作,后面很多分布数据库也都是基于这一篇论文的理论建立起来的。

2 机制

LSM Tree的出现是为了大数据量的OLAP场景,其最大的机制也可以说是优势是可以充分利用磁盘顺序写的优势而带来非常强大的数据写入性能,当然在查询这块牺牲了一定性能一般来说是慢于B Tree,当然这个性能也是可以接受的。而随着内存与SSD价格的持续走低以及容量的极大提升,基于LSM Tree的数据库读性能也有了显著提升。
一个简单版本的LSM Tree包含两层类似于树状的数据架构:

  • Memtable(内存表)完全驻留在内存中(定义为T0组件)
  • SSTable(Sorted String Table)存储在磁盘上(定义为T1组件)

在这里插入图片描述
新纪录被插入到Memtable中(T0组件)。如果插入导致T0组件超过一定的大小阈值,则从T0中删除一个连续的条目段,并将其合并到磁盘上的SSTable(T1组件)中。

3 组件

LSM Tree主要使用3个组件来优化读写操作:

Sorted String Table (SSTables):

数据按排序顺序排序的,因此无论何时读取数据,在最坏的情况下,其时间复杂度将为O(Log(N)),其中N是数据库表中的条目数。
在这里插入图片描述

Memtable

这是一个内存结构;
以排序方式存储数据;
作为回写(Write-Back)缓存;
当到达一定大小时将作为SSTable刷入数据库;
当磁盘中SSTable的数量增加时,如果某些key不存在于记录中时:

  • 要查询这些key,需要读取所有SSTable,这增加了读取时间的复杂度
  • 为了克服这个问题,Bloom filter出现了
  • Bloom filter是一种节省空间的数据结构,它可以告诉我们记录中是否缺少key,准确率为99.9%
  • 要使用此filter,我们可以在写入数据的时候向其添加记录,并在读取请求开始时检查key,以便在请求第一次出现时更有效地服务请求

在这里插入图片描述

Compaction:

直接翻译过来就是压实:
磁盘中以SSTable的形式存储数据时,假设有N个SSTable,每个表的大小为M;
最坏情况下,读取时间复杂度为O(N* Log(M)),因此,随着SSTable数量的增加,读时间复杂度也会增加;
此外,当我们只是刷新数据库中的SSTable时,相同的Key存在于多个SSTable中;
这时候Compactor就能发挥作用,compactor在后台运行,合并SSTable并删除相同的多行,并添加最新数据的新键,并将它们存储在新的合并/压缩的SSTable中。
在这里插入图片描述
在这里插入图片描述
正是这一组件,许多基于LSM Tree的分布式数据库也在标榜自己在存储侧的压缩能力,可以节省存储成本。

4 问题

LSM Tree既然有较强的写入响应能力,存储节省能力,那么LSM Tree就没有缺点么?

  • 还是借用吕海波老师的总结:“LSMTree最主要的问题,它是针对OLAP。底层Skiplist,锁的粒度要么太细,锁太多。要么锁粒度太粗,锁一大段链表。传通架构,锁就在块上,块上加个Pin,比Skiplist的并发性要好。”(说真的这句话看的不是太明白)
  • 读性能偏低,但是在强大硬件和分布式MPP加持下也能带来不错的读性能
  • 写放大,还是那句话,NVMe SSD上那都不是事
  • 延迟合并带来的不一致,特别是分布式架构同分片不同节点合并进度不同,可能导致连续两次在不同节点查询的结果不一致,当然这些都是可以通过一些技术手段解决的
  • 等等等等

总结

这不是我一个擅长的领域,以前没有接触过,也是翻了不少英文文档来写这一篇文章,可能还有些东西是不对的,也是一种尝试吧,也想着去看看国产分布式数据库引以为傲的底层。
老规矩,不知道写了些啥。

相关文章:

  • openFeign服务调用
  • 惊人技术!重新定义人机互动:深入了解神经链接的脑机接口技术
  • Android studio 花式按键
  • 【AIGC-图片生成视频系列-6】SSR-Encoder:用于主题驱动生成的通用编码器
  • Golang高质量编程与性能调优实战
  • 分类模型评估方法
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)创建并初始化TcpServer实例 以及 启动
  • C#编程-使用集合
  • 基于SSM的校园二手交易平台
  • StreamPark + PiflowX 打造新一代大数据计算处理平台
  • 软件测试错题集(黑盒、白盒测试)
  • wsl(ubuntu)创建用户
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • 终端上的GitHub Copilot以及IDE上的GitHub Copilot
  • MySQL之CRUD、常见函数及union查询
  • 5、React组件事件详解
  • Angular Elements 及其运作原理
  • js操作时间(持续更新)
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • SQL 难点解决:记录的引用
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue学习第二天
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从零搭建Koa2 Server
  • 反思总结然后整装待发
  • 飞驰在Mesos的涡轮引擎上
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 通过几道题目学习二叉搜索树
  • - 转 Ext2.0 form使用实例
  • Hibernate主键生成策略及选择
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • # Panda3d 碰撞检测系统介绍
  • #{}和${}的区别?
  • (33)STM32——485实验笔记
  • (floyd+补集) poj 3275
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (javascript)再说document.body.scrollTop的使用问题
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (多级缓存)缓存同步
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (论文阅读40-45)图像描述1
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (学习日记)2024.01.09
  • (转)我也是一只IT小小鸟
  • **PHP二维数组遍历时同时赋值
  • .java 9 找不到符号_java找不到符号
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 的程序集加载上下文
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET6 开发一个检查某些状态持续多长时间的类