下午听了关于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树的存储机制简述的更多相关文章

  1. HBase LSM树存储引擎详解

    1.前提 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎. B树存储引擎. LSM树(Log-Structured Merge Tree)存储引擎. 2. 哈希 ...

  2. 面对key数量多和区间查询低效问题:Hash索引趴窝,LSM树申请出场

    摘要:Hash索引有两个明显的限制:(1)当key的数量很多时,维护Hash索引会给内存带来很大的压力:(2)区间查询很低效.如何对这两个限制进行优化呢?这就轮到本文介绍的主角,LSM树,出场了. 我 ...

  3. LSM树由来、设计思想以及应用到HBase的索引

    讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎  是哈希表的持久化实现,支持增.删.改以及随机读取操作,但不支持顺序扫描,对应的存储系统为key-value存储 ...

  4. LSM树由来、设计思想以及应用到HBase的索引(转)

    转自: http://www.cnblogs.com/yanghuahui/p/3483754.html 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎  是哈 ...

  5. 为什么选择b+树作为存储引擎索引结构

    为什么选择b+树作为存储引擎索引结构 在数据库或者存储的世界里,存储引擎的角色一直处于核心位置.往简单了说,存储引擎主要负责数据如何读写.往复杂了说,怎么快速.高效的完成数据的读写,一直是存储引擎要解 ...

  6. LSM树以及在hbase中的应用

    转自:http://www.cnblogs.com/yanghuahui/p/3483754.html 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎  是哈希 ...

  7. 17-看图理解数据结构与算法系列(NoSQL存储-LSM树)

    关于LSM树 LSM树,即日志结构合并树(Log-Structured Merge-Tree).其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想.大多NoSQL数据库核心思想都是基于L ...

  8. 看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文

    <看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的样子. 关于LSM树 ...

  9. MongoDB索引存储BTree与LSM树(转载)

    1.为什么 MongoDB 使用B-树,而不是B+树 MongoDB 是一种 nosql,也存储在磁盘上,被设计用在数据模型简单,性能要求高的场合.性能要求高,我们看B-树与B+树的区别: B+树内节 ...

  10. 【转帖】LSM树 和 TSM存储引擎 简介

    LSM树 和 TSM存储引擎 简介 2019-03-08 11:45:23 长烟慢慢 阅读数 461  收藏 更多 分类专栏: 时序数据库   版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...

随机推荐

  1. Ros入门21讲

    一.ROS是什么? ROS=通信机制+开发工具+应用功能+生态系统 目的:提高机器人研发中的软件复用率. 1.ROS中的通信机制 松耦合分布式通信: 注意:什么是耦合.紧耦合.松耦合? 1.1 耦合 ...

  2. Python实验报告——第3章 流程控制语句

    实验报告 [实验目的] 1.掌握python中流程控制语句的使用,并能够应用到实际开发中. [实验条件] 1.PC机或者远程编程环境 [实验内容] 1.完成第三章流程控制语句实例01-09,实战一到实 ...

  3. Minio服务限制/租户

    官方文档地址:http://docs.minio.org.cn/docs/master/minio-server-limits-per-tenant 纠删码 (多块硬盘 / 服务) 浏览器访问 Lim ...

  4. Redis可视化工具(支持ssh链接)

    1.Redis Desktop Manager RedisDesktopManager,简称RDM,这是一款很出名的Redis可视化管理工具,支持Windows,Mac,Ipad,LInux 开源地址 ...

  5. SecureCRT使用之自动记录日志功能

    自动记录日志功能: 选择"选项"--"全局选项",打开全局选项,在常规设置中找到"默认会话"设置项,点击右侧的"编辑默认设置&qu ...

  6. 一文搞定 Spring事务

    Spring 事务 上文 使用SpringJDBC 1.JDBC事务控制 ​ 不管你现在使用的是那一种ORM开发框架,只要你的核心是JDBC,那么所有的事务处理都是围绕着JDBC开展的,而JDBC之中 ...

  7. NSIS使用API创建工具提示条和超级链接

    不再借助专用插件创建超级链接和工具提示条 !includensDialogs.nsh #编写:水晶石 Name "link_tooltips" OutFile "link ...

  8. SpringBoot的starter到底是什么?

    前言 我们都知道,Spring的功能非常强大,但也有些弊端.比如:我们需要手动去配置大量的参数,没有默认值,需要我们管理大量的jar包和它们的依赖. 为了提升Spring项目的开发效率,简化一些配置, ...

  9. css3_媒介查询

    !!!做媒介查询页面大小时,一定要加: <meta name="viewport" content="width=device-width, initial-sca ...

  10. Kafka 之producer拦截器(interceptor)

    Kafka 之producer拦截器(interceptor) 一.拦截器原理 Producer拦截器(interceptor)是在Kafka 0.10版本被引入的,主要用于实现clients端的定制 ...