看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文
《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种排序等等几十篇的样子。
关于LSM树
LSM树,即日志结构合并树(Log-Structured Merge-Tree)。其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想。大多NoSQL数据库核心思想都是基于LSM来做的,只是具体的实现不同。所以本来不打算列入该系列,但是有朋友留言了好几次让我讲LSM树,那么就说一下LSM树。
LSM树诞生背景
传统关系型数据库使用btree或一些变体作为存储结构,能高效进行查找。但保存在磁盘中时它也有一个明显的缺陷,那就是逻辑上相离很近但物理却可能相隔很远,这就可能造成大量的磁盘随机读写。随机读写比顺序读写慢很多,为了提升IO性能,我们需要一种能将随机操作变为顺序操作的机制,于是便有了LSM树。LSM树能让我们进行顺序写磁盘,从而大幅提升写操作,作为代价的是牺牲了一些读性能。
关于磁盘IO
磁盘读写时涉及到磁盘上数据查找,地址一般由柱面号、盘面号和块号三者构成。也就是说移动臂先根据柱面号移动到指定柱面,然后根据盘面号确定盘面的磁道,最后根据块号将指定的磁道段移动到磁头下,便可开始读写。
整个过程主要有三部分时间消耗,查找时间(seek time) +等待时间(latency time)+传输时间(transmission time) 。分别表示定位柱面的耗时、将块号指定磁道段移到磁头的耗时、将数据传到内存的耗时。整个磁盘IO最耗时的地方在查找时间,所以减少查找时间能大幅提升性能。
LSM树原理
LSM树由两个或以上的存储结构组成,比如在论文中为了方便说明使用了最简单的两个存储结构。一个存储结构常驻内存中,称为C0 tree,具体可以是任何方便健值查找的数据结构,比如红黑树、map之类,甚至可以是跳表。另外一个存储结构常驻在硬盘中,称为C1 tree,具体结构类似B树。C1所有节点都是100%满的,节点的大小为磁盘块大小。
插入步骤
大体思路是:插入一条新纪录时,首先在日志文件中插入操作日志,以便后面恢复使用,日志是以append形式插入,所以速度非常快;将新纪录的索引插入到C0中,这里在内存中完成,不涉及磁盘IO操作;当C0大小达到某一阈值时或者每隔一段时间,将C0中记录滚动合并到磁盘C1中;对于多个存储结构的情况,当C1体量越来越大就向C2合并,以此类推,一直往上合并Ck。
合并步骤
合并过程中会使用两个块:emptying block和filling block。
从C1中读取未合并叶子节点,放置内存中的emptying block中。从小到大找C0中的节点,与emptying block进行合并排序,合并结果保存到filling block中,并将C0对应的节点删除。不断执行第2步操作,合并排序结果不断填入filling block中,当其满了则将其追加到磁盘的新位置上,注意是追加而不是改变原来的节点。合并期间如故宫emptying block使用完了则再从C1中读取未合并的叶子节点。C0和C1所有叶子节点都按以上合并完成后即完成一次合并。
关于优化措施
本文用图阐述LSM的基本原理,但实际项目中其实有很多优化策略,而且有很多针对LSM树优化的paper。比如使用布隆过滤器快速判断key是否存在,还有做一些额外的索引以帮助更快找到记录等等。
插入操作
向LSM树中插入
A E L R U
,首先会插入到内存中的C0树上,这里使用AVL树,插入“A”,先项磁盘日志文件追加记录,然后再插入C0,
插入“E”,同样先追加日志再写内存,
继续插入“L”,旋转后如下,
插入“R”“U”,旋转后最终如下。
假设此时触发合并,则因为C1还没有树,所以emptying block为空,直接从C0树中依次找最小的节点。filling block长度为4,这里假设磁盘块大小为4。
开始找最小的节点,并放到filling block中,
继续找第二个节点,
以此类推,填满filling block,
开始写入磁盘,C1树,
继续插入
B F N T
,先分别写日志,然后插入到内存的C0树中,
假如此时进行合并,先加载C1的最左边叶子节点到emptying block,
接着对C0树的节点和emptying block进行合并排序,首先是“A”进入filling block,
然后是“B”,
合并排序最终结果为,
将filling block追加到磁盘的新位置,将原来的节点删除掉,
继续合并排序,再次填满filling block,
将filling block追加到磁盘的新位置,上一层的节点也要以磁盘块(或多个磁盘块)大小写入,尽量避开随机写。另外由于合并过程可能会导致上层节点的更新,可以暂时保存在内存,后面在适当时机写入。
查找操作
查找总体思想是先找内存的C0树,找不到则找磁盘的C1树,然后是C2树,以此类推。
假如要找“B”,先找C0树,没找到。
接着找C1树,从根节点开始,
找到“B”。
删除操作
删除操作为了能快速执行,主要是通过标记来实现,在内存中将要删除的记录标记一下,后面异步执行合并时将相应记录删除。
比如要删除“U”,假设标为#的表示删除,则C0树的“U”节点变为,
而如果C0树不存在的记录,则在C0树中生成一个节点,并标为#,查找时就能在内存中得知该记录已被删除,无需去磁盘找了。比如要删除“B”,那么没有必要去磁盘执行删除操作,直接在C0树中插入一个“B”节点,并标为#。
看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文的更多相关文章
- 17-看图理解数据结构与算法系列(NoSQL存储-LSM树)
关于LSM树 LSM树,即日志结构合并树(Log-Structured Merge-Tree).其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想.大多NoSQL数据库核心思想都是基于L ...
- 09-看图理解数据结构与算法系列(B树)
B树 B树即平衡查找树,一般理解为平衡多路查找树,也称为B-树.B_树.是一种自平衡树状数据结构,能对存储的数据进行O(log n)的时间复杂度进行查找.插入和删除.B树一般较多用在存储系统上,比如数 ...
- 06-看图理解数据结构与算法系列(AVL树)
AVL树 AVL树,也称平衡二叉搜索树,AVL是其发明者姓名简写.AVL树属于树的一种,而且它也是一棵二叉搜索树,不同的是他通过一定机制能保证二叉搜索树的平衡,平衡的二叉搜索树的查询效率更高. AVL ...
- 19-看图理解数据结构与算法系列(Radix树)
Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...
- 13-看图理解数据结构与算法系列(Trie树)
Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...
- 11-看图理解数据结构与算法系列(B树的删除)
删除操作 删除操作比较复杂,主要是因为删除的项可能在叶子节点上也可能在非叶子节点上,而且删除后可能导致不符合B树的规定,这里暂且称之为导致B树不平衡,于是要进行一些合并.左旋.右旋等操作,使之符合B树 ...
- 10-看图理解数据结构与算法系列(B+树)
B+树 B+树是B树的一种变体,也属于平衡多路查找树,大体结构与B树相同,包含根节点.内部节点和叶子节点.多用于数据库和操作系统的文件系统中,由于B+树内部节点不保存数据,所以能在内存中存放更多索引, ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
随机推荐
- MongoDB 概述
一.概述: 1.NoSQL数据库(非关系型数据库) 2.文档存储 3.格式类似JSON,BSON 4.最终一致性(非ACID) , CAP定理(C 一致性,A 高可用,P 分区性) 5.高可扩展性(分 ...
- volatile 作用
volatile使用场景:线程间共享变量需要使用 volatile 关键字标记,确保线程能够读取到更新后的最新变量值. volatile关键字的目的是告诉虚拟机: 1.每次访问变量时,总是获取主内存的 ...
- C# vb .net实现旋转特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的旋转特效呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...
- 二 python并发编程之多进程实现
一 multiprocessing模块介绍 二 process类的介绍 三 process类的使用 四 守护进程 五 进程同步(锁) 六 队列 七 管道 八 共享数据 九 信号量 十 事件 十一 进程 ...
- 拓展 - WebRTC 多视频网络拓扑之三种架构
众所周知,WebRTC非常适合点对点(即一对一)的音视频会话.然而,当我们的客户要求超越一对一,即一对多.多对一设置多对多的解决方案或者服务,那么问题就来了:“我们应该采用什么样的架构?” .简单的呢 ...
- data:image/png;base64应用
原文:https://blog.csdn.net/deng_xj/article/details/93731850 data:image/png;base64应用 我们知道任何图片都可以通过base6 ...
- Java 之 Maven 基础
一.Maven 介绍 1.什么是 Maven Maven 是一个项目管理工具,它包含了一个项目对象模型(POM:Project Object Model),一组标准集合,一个项目生命周期(Projec ...
- POSIX多线程之创建线程pthread_create && 线程清理pthread_cleanup
多线程之pthread_create创建线程 pthreads定义了一套C程序语言类型.函数.与常量.以pthread.h和一个线程库实现. 数据类型: pthread_t:线程句柄 pthread_ ...
- 【RAC】 RAC For W2K8R2 安装--总体规划 (一)
[RAC] RAC For W2K8R2 安装--总体规划 (一) 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一 ...
- 爬虫入门urlib,urlib2的基本使用和进阶
python2中的urlib和urlib2 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的 ...