基于LSM树的存储机制简述
下午听了关于MyRocks-PASV的研究讲座,很有意思所以学习了一下LSM树的一些简单的底层原理。现在整理一下
我们都知道目前Key:Value型的数据库普遍较之关系型数据库有着更好的表现,为什么会有这样的一个差异呢?关键就在于存储形式和读写机制的不同。Key:Value型数据库可以通过LSM Tree(Log-Structured-Merge-Tree)来进行存储,而以MySQL为代表的关系型数据库则以B+树的形式来组织聚簇索引文件和二级索引文件来进行存储。二者的实现机制由于是否顺序写产生了很大的差别。
LSM树的具体机制
LSM树其实并不是一个真正意义上的树形结构,其核心特点是利用顺序写来提高写性能,顺序写很好理解。举个很多人都背过的例子就是MySQL的InnoDB引擎在写入内容时会首先通过WAL机制,先将改动写进磁盘中的redo log这个物理日志中,物理日志记录的是对某表的某数据页某偏移量处做了某更新,然后再找机会把redo log中的内容刷进磁盘中真正存储数据的地方。这么做的好处就是因为写入物理日志只需要接着之前写到的位置往下写就行,不需要随机存取磁盘内容,可以进行的相对快速。
但问题就是,MySQL终究还是要把redo log中的操作写入磁盘中真正存储数据的地方,而这个动作就限制了关系型数据库的性能发挥。而LSM树就是直接将WAL机制作为存储数据的主要机制来实现数据库的存取。
如图所示,LSM树有以下三个重要组成部分
- MemTable
- Immutable MemTable
- SS Table
MemTable
MemTable是在内存中的数据结构,用于保存最近更新的数据操作,这里会按照Key有序地组织这些数据。至于具体如何组织这些数据以使其按照Key有序,LSM树并没有做出相应的规定,可以自行实现。
要注意的是因为数据暂时保存在内存中,那么如果断电了就会存在丢失数据的风险,因此这里还是会跟InnoDB一样通过WAL机制来写入磁盘,以保证数据不会因为崩溃或断电而丢失。
Immutable MemTable
当MemTable存储的数据达到阈值后,就会将该Memtable就地转化成Immutable MemTable。Immutable MemTable是将转MemTable变为SSTable的一种中间状态。你可以理解其为一个暂存文件,该文件不再继续写入,而是等待刷入磁盘的SSTable中。之后的写入工作则由一个新创建的MemTable处理。
SSTable(Sorted String Table)
其本质是有序键值对的集合文件,是LSM树在磁盘中的数据结构,我们可以建立key的索引来加快查找。
重点来了,LSM树会将所有的数据插入、修改、删除等操作记录(注意是操作记录)保存在内存之中,当此类操作达到一定的数据量后,再批量地顺序写入到磁盘当中。注意,这与B+树不同,B+树数据的更新会直接在原数据所在处修改对应的值,但是LSM数的数据更新是日志式的,就跟上面说的WAL机制的redo log一样,一条数据更新是直接将更新记录写进log的最后来完成的。而这样设计的目的就是为了顺序写,我们只需要不断地将Immutable MemTable刷入磁盘进行持久化存储即可,不用去修改之前的SSTable中的key,也就保证了顺序写,提升了效率。
不过不断地向后写也就意味着,在不同的SSTable中,可能存在相同Key的记录,显然最新的那条记录才是真实的。那么这样设计的虽然大大提高了写性能,但同时也会带来一些问题:
- 冗余存储,对于某个key,除了最新的那条记录外,其他的记录都是冗余无用的,但是仍然占用了存储空间。这里LSM树引入了Compact操作(合并多个SSTable)来清除冗余的记录。
- 读取时需要从最新的记录反向进行查询,直到找到某个key的记录。最坏情况需要查询完所有的SSTable,这里可以通过索引/布隆过滤器来优化查找速度。
Compact策略
讲到SSTable,我们可以看到这里从MemTable到SSTable一路下来全是顺序写的,问题是磁盘容量并不是无限的,何况SSTable中实际上的真实数据只有最新的那一条,所以如何对SSTable进行Compact来释放空间是很重要的。
Compact释放空间的策略讲到底就是围绕着三大性能的权衡策略。即在以下三个问题中,我们必须至少接受其中之一:
- 读放大:读取数据时实际读取的数据量大于真正的数据量。
- 例如在LSM树中需要先在MemTable查看当前key是否存在,不存在继续从SSTable中寻找。
- 写放大:写入数据时实际写入的数据量大于真正的数据量。
- 例如在LSM树中写入时可能触发Compact操作,导致实际写入的数据量远大于该key的数据量。
- 空间放大:数据实际占用的磁盘空间比数据的真正大小更多。
- 上面提到的冗余存储,对于一个key来说,只有最新的那条记录是有效的,而之前的记录都是可以被清理回收的。
size-tiered 策略
简单来说就是把SSTable分层,限制各层的SSTable数量,并且要求每一层的SSTable的大小都要相近,注意不是相同。当上层SSTable过多时,就将多出来的SSTable合并,作为一个更大的SSTable存入下一层。
可以看出,当层数达到一定数量时,最底层的单个SSTable的大小会变得非常大。而且这种策略会导致空间放大严重。因为即使对于同一层的SSTable,每个key的记录是可能存在多份的,只有当该层的SSTable执行compact操作才会消除这些key的冗余记录,那么积累到整个结构中,冗余的记录占比可想而知。
leveled 策略
leveled策略也是采用分层的思想,与size-tiered策略不同的地方在于,leveled策略会将每一层切分成多个大小相近的SSTable,并且保证这些SSTable是这一层是全局有序的,而这就意味着一个key在每一层至多只有1条记录,不存在冗余记录。
Leveled策略是通过合并策略来保证每一层的SSTable全局有序的。具体实现方法为当某一层总大小超过限制,那么选择该层中与下一层存在交集的SSTable文件进行合并并放入下一层,重复这个操作直到该层大小恢复到限制以内为止。并且,多个不相干的合并是可以并发进行的,这大大提高了效率。
这种策略极大缓解了空间放大的问题,但是代价是写放大问题更加突出。在最坏的情况下,如果该层某个SSTable的key的范围跨度非常大,覆盖了下一层所有key的范围,那么进行Compact时将涉及下一层的全部数据。
不过这里只是简单的聊了一下这些机制,具体使用LSM树进行存储的那些应用中,基本都对它们进行了进一步的优化。这里不再细说
基于LSM树的存储机制简述的更多相关文章
- HBase LSM树存储引擎详解
1.前提 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎. B树存储引擎. LSM树(Log-Structured Merge Tree)存储引擎. 2. 哈希 ...
- 面对key数量多和区间查询低效问题:Hash索引趴窝,LSM树申请出场
摘要:Hash索引有两个明显的限制:(1)当key的数量很多时,维护Hash索引会给内存带来很大的压力:(2)区间查询很低效.如何对这两个限制进行优化呢?这就轮到本文介绍的主角,LSM树,出场了. 我 ...
- LSM树由来、设计思想以及应用到HBase的索引
讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎 是哈希表的持久化实现,支持增.删.改以及随机读取操作,但不支持顺序扫描,对应的存储系统为key-value存储 ...
- LSM树由来、设计思想以及应用到HBase的索引(转)
转自: http://www.cnblogs.com/yanghuahui/p/3483754.html 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎 是哈 ...
- 为什么选择b+树作为存储引擎索引结构
为什么选择b+树作为存储引擎索引结构 在数据库或者存储的世界里,存储引擎的角色一直处于核心位置.往简单了说,存储引擎主要负责数据如何读写.往复杂了说,怎么快速.高效的完成数据的读写,一直是存储引擎要解 ...
- LSM树以及在hbase中的应用
转自:http://www.cnblogs.com/yanghuahui/p/3483754.html 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎 是哈希 ...
- 17-看图理解数据结构与算法系列(NoSQL存储-LSM树)
关于LSM树 LSM树,即日志结构合并树(Log-Structured Merge-Tree).其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想.大多NoSQL数据库核心思想都是基于L ...
- 看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文
<看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的样子. 关于LSM树 ...
- MongoDB索引存储BTree与LSM树(转载)
1.为什么 MongoDB 使用B-树,而不是B+树 MongoDB 是一种 nosql,也存储在磁盘上,被设计用在数据模型简单,性能要求高的场合.性能要求高,我们看B-树与B+树的区别: B+树内节 ...
- 【转帖】LSM树 和 TSM存储引擎 简介
LSM树 和 TSM存储引擎 简介 2019-03-08 11:45:23 长烟慢慢 阅读数 461 收藏 更多 分类专栏: 时序数据库 版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...
随机推荐
- centos7部署Prometheus+Grafana
一.安装Prometheus Server 请从 Prometheus 官方下载 linux 版的二进制压缩包.注意在下载前要选择操作系统为 linux. 执行下面的命令把 prometheus se ...
- js中new的原理
面向对象 在了解new的原理之前,先简单地了解一下构造函数和对象. js可以通过构造函数创建对象: function Test() { } var t = new Test(); 构造函数的首字母大写 ...
- JS数据结构之 Map
JS数据结构之 Map Map介绍 Map(映射)是ES6引入的一种数据结构.这是一种存储键值对列表很方便的方法,类似于其他编程语言的哈希表. HashMap(哈希表),也叫做散列表.是根据关键码值 ...
- .NET 6当中的Web API版本控制
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 为了了解ASP.NET Core Web API的版本控制,我们必须了解API中的 ...
- 萌新码农的第一篇:MarkDown的使用方法
MarkDown的使用方法 使用的编辑软件Typora 1.标题的使用方法 输入''#''然后空格,输入标题名字即可生成标题. 随着''#''的增多,标题的大小会依次减小,最多到六级标题 2.排字 字 ...
- Redis从入门到高级笔记【涵盖重点面试题】
NoSQL数据库 DBEngines网站中会统计目前数据库在全世界的排名 1.1 什么是NoSQL 最常见的解释是"non-relational",很多人说它是"Not ...
- DML添加数据-删除数据-修改数据
DML添加数据 语法 insert into 表名(列名1,列名2,列名n) values(值1,值2,值n) 列:INSERT INTO day02(id,NAME,age) VALUES(1,&q ...
- 驱动开发:内核遍历进程VAD结构体
在上一篇文章<驱动开发:内核中实现Dump进程转储>中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍VAD结构,该结构的全程是Virtual Address Descrip ...
- Explain:你见过这样的Sql吗?
上一篇我们讲到Mysql索引底层逻辑,为了了解后续sql知识,我们还是需要先学习一下相关"工具"得使用 一.Explain介绍 EXPLAIN是MySQl必不可少的一个分析工具,主 ...
- NOIP2017总结 & 题解
day1t1的结论貌似在哪见过,自己稍微验证了一下貌似没记错就没有管了.t2一道很好(keng)的模拟题啊t3自己做题好慢啊,想出来dp打上去最后几分钟才过了大样例,我写的是记忆化搜索,判-1很好判, ...