精华内容
下载资源
问答
  • LSM

    千次阅读 2018-01-26 11:43:47
    LSM是用来被设计比传统的B+树有更好的写操作吞吐量,通过消去随机的本地更新操作来达到这目标。 之所以LSM成为了一好方法,本质原因是随机读写慢,顺序读写快。 简单来说,磁盘读取时间包括三方面: 1.寻道...

    Log Structed Merge Trees(LSM)

    LSM是用来被设计比传统的B+树有更好的写操作吞吐量,通过消去随机的本地更新操作来达到这个目标。

    之所以LSM成为了一个好方法,本质原因是随机读写慢,顺序读写快。

    简单来说,磁盘读取时间包括三方面:

    1.寻道时间,表示磁头在不同磁道之间移动。

    2.旋转延迟,表示在磁道找到时,中轴带动盘面旋转到合适的扇区开头处。

    3.传输时间,表示盘面继续转动,实际读取数据的时间。

    整个过程1、2占了主体,3几乎不消耗时间。量级上是3个量级的差距,这就为优化提供了前提。

    因而,在对写操作敏感的时候,一个最好的办法是简单地将数据添加到文件。这个策略经常被使用在日志或者堆文件,因其是完全顺序的,所以可以提供非常好的写操作性能,大约等于磁盘的理论速度,也就是200~300MB/S。

      因为简单和高效,基于日志的策略在大数据之间越来越流行,同时他们也有一些缺点,从日志文件中读一些数据将会比写操作需要更多的时间,需要倒序扫描,直接找到所需的内容。

      这说明日志仅仅适用于一些简单的场景:

      1. 数据是被整体访问,像大部分数据库的WAL(write-ahead log) 

      2. 知道明确的offset,比如在Kafka中。

    所以,我们需要更多的日志来为更复杂的读场景(比如按key或者range)提供高效的性能,这儿有4个方法可以完成这个,它们分别是:

    1. 二分查找: 将文件数据有序保存,使用二分查找来完成特定key的查找。
    2. 哈希:用哈希将数据分割为不同的bucket
    3. B+树:使用B+树 或者 ISAM 等方法,可以减少外部文件的读取
    4. 外部文件: 将数据保存为日志,并创建一个hash或者查找树映射相应的文件
    所有的方法都可以有效的提高了读操作的性能(最少提供了O(log(n)) ),但是,却丢失了日志文件超好的写性能。上面这些方法,都强加了总体的结构信息在数据上,数据被按照特定的方式放置,所以可以很快的找到特定的数据,但是却对写操作不友善,让写操作性能下降。
    更糟糕的是,当我们需要更新hash或者B+树的结构时,需要同时更新文件系统中特定的部分,这就是上面说的比较慢的随机读写操作。这种随机的操作要尽量减少.
    所以这就是 LSM 被发明的原理, LSM 使用一种不同于上述四种的方法,保持了日志文件写性能,以及微小的读操作性能损失。本质上就是让所有的操作顺序化,而不是像散弹枪一样随机读写。

    很多树结构可以不用 update-in-place,最流行就是

    append-only Btreehttp://www.bzero.se/ldapd/btree.html
    

    ,也称为 Copy-On-Write Tree。他们通过顺序的在文件末尾重复写对结构来实现写操作,之前的树结构的相关部分,包括最顶层结点都会变成孤结点。尽管通过这种方法避免了本地更新,但是因为每个写操作都要重写树结构,放大了写操作,降低了写性能。

    The Base LSM Algorithm

    从概念上说,最基本的LSM是很简单的 。将之前使用一个大的查找结构(造成随机读写,影响写性能),变换为将写操作顺序的保存到一些相似的有序文件(也就是sstable)中。所以每个文件包 含短时间内的一些改动。因为文件是有序的,所以之后查找也会很快。文件是不可修改的,他们永远不会被更新,新的更新操作只会写到新的文件中。读操作检查很有的文件。通过周期性的合并这些文件来减少文件个数。

    让我们更具体的看看,当一些更新操作到达时,他们会被写到内存缓存(也就是memtable)中,memtable使用树结构来保持key的有序,在大部 分的实现中,memtable会通过写WAL的方式备份到磁盘,用来恢复数据,防止数据丢失。当memtable数据达到一定规模时会被刷新到磁盘上的一 个新文件,重要的是系统只做了顺序磁盘读写,因为没有文件被编辑,新的内容或者修改只用简单的生成新的文件。
    所以越多的数据存储到系统中,就会有越多的不可修改的,顺序的sstable文件被创建,它们代表了小的,按时间顺序的修改。
    因为比较旧的文件不会被更新,重复的纪录只会通过创建新的纪录来覆盖,这也就产生了一些冗余的数据。
    所以系统会周期的执行合并操作(compaction)。 合并操作选择一些文件,并把他们合并到一起,移除重复的更新或者删除纪录,同时也会删除上述的冗余。更重要的是,通过减少文件个数的增长,保证读操作的性能。因为sstable文件都是有序结构的,所以合并操作也是非常高效的。
    当一个读操作请求时,系统首先检查内存数据(memtable),如果没有找到这个key,就会逆序的一个一个检查sstable文件,直到key 被找到。因为每个sstable都是有序的,所以查找比较高效(O(logN)),但是读操作会变的越来越慢随着sstable的个数增加,因为每一个 sstable都要被检查。(O(K log N), K为sstable个数, N 为sstable平均大小)。
    所以,读操作比其它本地更新的结构慢,幸运的是,有一些技巧可以提高性能。最基本的的方法就是页缓存(也就是leveldb的 TableCache,将sstable按照LRU缓存在内存中)在内存中,减少二分查找的消耗。LevelDB 和 BigTable 是将 block-index 保存在文件尾部,这样查找就只要一次IO操作,如果block-index在内存中。一些其它的系统则实现了更复杂的索引方法。
    即使有每个文件的索引,随着文件个数增多,读操作仍然很慢。通过周期的合并文件,来保持文件的个数,因些读操作的性能在可接收的范围内。即便有了合 并操作,读操作仍然会访问大量的文件,大部分的实现通过布隆过滤器来避免大量的读文件操作,布隆过滤器是一种高效的方法来判断一个sstable中是否包 含一个特定的key。(如果bloom说一个key不存在,就一定不存在,而当bloom说一个文件存在是,可能是不存在的,只是通过概率来保证)。
    所有的写操作都被分批处理,只写到顺序块上。另外,合并操作的周期操作会对IO有影响,读操作有可能会访问大量的文件(散乱的读)。这简化了算法工作的方法,我们交换了读和写的随机IO。这种折衷很有意义,我们可以通过软件实现的技巧像布隆过滤器或者硬件(大文件cache)来优化读性能。
    Basic Compaction

    为了保持LSM的读操作相对较快,维护并减少sstable文件的个数是很重要的,所以让我们更深入的看一下合并操作。这个过程有一点儿像一般垃圾回收算法。

    当一定数量的sstable文件被创建,例如有5个sstable,每一个有10行,他们被合并为一个50行的文件(或者更少的行数)。这个过程一 直持续着,当更多的有10行的sstable文件被创建,当产生5个文件时,它们就被合并到50行的文件。最终会有5个50行的文件,这时会将这5个50 行的文件合并成一个250行的文件。这个过程不停的创建更大的文件。

    上述的方案有一个问题,就是大量的文件被创建,在最坏的情况下,所有的文件都要搜索。

    Levelled Compaction

    更新的实现,像 LevelDB 和 Cassandra解决这个问题的方法是:实现了一个分层的,而不是根据文件大小来执行合并操作。这个方法可以减少在最坏情况下需要检索的文件个数,同时也减少了一次合并操作的影响。

    按层合并的策略相对于上述的按文件大小合并的策略有二个关键的不同:

    1. 每一层可以维护指定的文件个数,同时保证不让key重叠。也就是说把key分区到不同的文件。因此在一层查找一个key,只用查找一个文件。第一层是特殊情况,不满足上述条件,key可以分布在多个文件中。
    2. 每次,文件只会被合并到上一层的一个文件。当一层的文件数满足特定个数时,一个文件会被选出并合并到上一层。这明显不同与另一种合并方式:一些相近大小的文件被合并为一个大文件。

    这些改变表明按层合并的策略减小了合并操作的影响,同时减少了空间需求。除此之外,它也有更好的读性能。但是对于大多数场景,总体的IO次数变的更多,一些更简单的写场景不适用。

    总结

    所以, LSM 是日志和传统的单文件索引(B+ tree,Hash Index)的中立,他提供一个机制来管理更小的独立的索引文件(sstable)。

    通过管理一组索引文件而不是单一的索引文件,LSM 将B+树等结构昂贵的随机IO变的更快,而代价就是读操作要处理大量的索引文件(sstable)而不是一个,另外还是一些IO被合并操作消耗。





    本文参考链接:https://www.zhihu.com/question/19887265/answer/78839142















    展开全文
  • LSM

    万次阅读 多人点赞 2019-06-26 19:14:08
    其实它并不属于一具体的数据结构,它更是一种数据结构的设计思想。大多NoSQL数据库核心思想都是基于LSM来做的,只是具体的实现不同。所以本来不打算列入该系列,但是有朋友留言了好几次让我讲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”节点,并标为#。

     

    假如对写操作的吞吐量比较敏感,可采用日志策略(顺序读写,只追加不修改)来提升写性能。存在问题:数据查找需要倒序扫描,花费很多时间。比如,预写日志WAL,WAL的中心概念是数据文件(存储着表和索引)的修改必须在这些动作被日志记录之后才被写入,即在描述这些改变的日志记录被刷到持久存储以后。如果我们遵循这种过程,我们不需要在每个事务提交时刷写数据页面到磁盘,因为我们知道在发生崩溃时可以使用日志来恢复数据库:任何还没有被应用到数据页面的改变可以根据其日志记录重做(这是前滚恢复,也被称为REDO)。使用WAL可以显著降低磁盘的写次数,因为只有日志文件需要被刷出到磁盘以保证事务被提交,而被事务改变的每一个数据文件则不必被刷出。

    其只是提高了写的性能,对于更为复杂的读性能,需要寻找其他的方法,其中有四种方法来提升读性能

    • 二分查找: 将文件数据有序保存,使用二分查找来完成特定key的查找。

    • 哈希:用哈希将数据分割为不同的bucket

    • B+树:使用B+树 或者 ISAM 等方法,可以减少外部文件的读取

    • 外部文件: 将数据保存为日志,并创建一个hash或者查找树映射相应的文件。

    所有的四种方法都可以有效的提高了读操作的性能(最少提供了O(log(n)) ),但是,却丢失了日志文件超好的写性能,上面这些方法,都强加了总体的结构信息在数据上,数据被按照特定的方式放置,所以可以很快的找到特定的数据,但是却对写操作不友善,让写操作性能下降。更糟糕的是,当需要更新hash或者B+树的结构时,需要同时更新文件系统中特定的部分,这就是造成了比较慢的随机读写操作,这种随机的操作要尽量减少。

    既要保证日志文件好的写性能,又要在一定程度上保证读性能,所以LSM-Tree应运而生。

    下面块为引用https://www.cnblogs.com/yanghuahui/p/3483754.html,进行对比

    讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来:

    1. 哈希存储引擎  是哈希表的持久化实现,支持增、删、改以及随机读取操作,但不支持顺序扫描,对应的存储系统为key-value存储系统。对于key-value的插入以及查询,哈希表的复杂度都是O(1),明显比树的操作O(n)快,如果不需要有序的遍历数据,哈希表就是your Mr.Right
    2. B树存储引擎是B树(关于B树的由来,数据结构以及应用场景可以看之前一篇博文)的持久化实现,不仅支持单条记录的增、删、读、改操作,还支持顺序扫描(B+树的叶子节点之间的指针),对应的存储系统就是关系数据库(Mysql等)。
    3. LSM树(Log-Structured Merge Tree)存储引擎和B树存储引擎一样,同样支持增、删、读、改、顺序扫描操作。而且通过批量存储技术规避磁盘随机写入问题。当然凡事有利有弊,LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提高写性能。

    LSM树(Log Structured Merge Tree,结构化合并树)的思想非常朴素,就是将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘(由此提升了写性能),是一种基于硬盘的数据结构,与B-tree相比,能显著地减少硬盘磁盘臂的开销。当然凡事有利有弊,LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提高写性能。

    读取时需要合并磁盘中的历史数据和内存中最近的修改操作,读取时可能需要先看是否命中内存,否则需要访问较多的磁盘文件(存储在磁盘中的是许多小批量数据,由此降低了部分读性能。但是磁盘中会定期做merge操作,合并成一棵大树,以优化读性能)。LSM树的优势在于有效地规避了磁盘随机写入问题,但读取时可能需要访问较多的磁盘文件。

    代表数据库:nessDB、leveldb、hbase等

    核心思想的核心就是放弃部分读能力,换取写入的最大化能力,放弃磁盘读性能来换取写的顺序性。极端的说,基于LSM树实现的HBase的写性能比Mysql高了一个数量级,读性能低了一个数量级。

    LSM操作

    LSM树 插入数据可以看作是一个N阶合并树。数据写操作(包括插入、修改、删除也是写)都在内存中进行,

    数据首先会插入内存中的树。当内存树的数据量超过设定阈值后,会进行合并操作。合并操作会从左至右便利内存中树的子节点 与 磁盘中树的子节点并进行合并,会用最新更新的数据覆盖旧的数据(或者记录为不同版本)。当被合并合并数据量达到磁盘的存储页大小时。会将合并后的数据持久化到磁盘,同时更新父节点对子节点的指针。

    LSM树 读数据 磁盘中书的非子节点数据也被缓存到内存中。在需要进行读操作时,总是从内存中的排序树开始搜索,如果没有找到,就从磁盘上的排序树顺序查找。

    在LSM树上进行一次数据更新不需要磁盘访问,在内存即可完成,速度远快于B+树。当数据访问以写操作为主,而读操作则集中在最近写入的数据上时,使用LSM树可以极大程度地减少磁盘的访问次数,加快访问速度。

    LSM树 删除数据 前面讲了。LSM树所有操作都是在内存中进行的,那么删除并不是物理删除。而是一个逻辑删除,会在被删除的数据上打上一个标签,当内存中的数据达到阈值的时候,会与内存中的其他数据一起顺序写入磁盘。 这种操作会占用一定空间,但是LSM-Tree 提供了一些机制回收这些空间。


    转载参考:https://baijiahao.baidu.com/s?id=1613810327967900833&wfr=spider&for=pc

                      https://blog.csdn.net/qq_28328381/article/details/81280197

    展开全文
  • 转自 李智慧 从零开始学大数据 传统的机械式磁盘的访问特性是连续读写很快,随机读写很慢。这是因为机械磁盘靠电机驱动访问磁盘上的数据,...数据写入的时候以Log方式连续写入,然后异步对磁盘上的多个LSM树进行合并。

    转自 李智慧 从零开始学大数据

    传统的机械式磁盘的访问特性是连续读写很快,随机读写很慢。这是因为机械磁盘靠电机驱动访问磁盘上的数据,电机要将磁头落到数据所在的磁道上,这个过程需要较长的寻址时间。如果数据不连续存储,磁头就要不停的移动,浪费了大量的时间。

    为了提高数据写入速度,HBase使用了一种叫作LSM树的数据结构进行数据存储。LSM树的全名是Log Structed Merge Tree,翻译过来就是Log结构合并树。数据写入的时候以Log方式连续写入,然后异步对磁盘上的多个LSM树进行合并。

    image-20201116142438864

    LSM树可以看作是一个N阶合并树。数据写操作(包括插入、修改、删除)都在内存中进行,并且都会创建一个新记录(修改会记录新的数据值,而删除会记录一个删除标志)。这些数据在内存中仍然还是一棵排序树,当数据量超过设定的内存阈值后,会将这棵排序树和磁盘上最新的排序树合并。当这棵排序树的数据量也超过设定阈值后,会和磁盘上下一级的排序树合并。合并过程中,会用最新更新的数据覆盖旧的数据(或者记录为不同版本)。

    在需要进行读操作时,总是从内存中的排序树开始搜索,如果没有找到,就从磁盘 上的排序树顺序查找。

    在LSM树上进行一次数据更新不需要磁盘访问,在内存即可完成。当数据访问以写操作为主,而读操作则集中在最近写入的数据上时,使用LSM树可以极大程度地减少磁盘的访问次数,加快访问速度。

    展开全文
  • 摘要:了解 B-tree 之外的存储引擎。LSM流行的高性能写的数据库实现方式。Log-Structured Merge-Tree,简称 LSM。以 Mysql、postgresq...

    摘要:了解 B-tree 之外的存储引擎。LSM 一个流行的高性能写的数据库实现方式。

    Log-Structured Merge-Tree,简称 LSM。

    以 Mysql、postgresql 为代表的传统 RDBMS 都是基于 b-tree 的 page-orented 存储引擎。现代计算机的最大处理瓶颈在磁盘的读写上,数据存储无法绕开磁盘的读写,纯内存型数据库除外,但由于内存存储的不稳定性,我们一般只将内存型的存储作为缓存系统。

    为提升数据库系统的写性能,我们发现磁盘的顺序写性能远远大于随机写性能,甚至性能高于内存的随机写。所以在很多偏向写性能的数据库系统中,以牺牲一部分读性能和增大写放大的情况下引入了 LSM 数据结构。

    设计一个数据库引擎

    我们从头开始设计一个数据库引擎。数据模型很简单,我们选最简单的 Key-Value 结构,一条数据只有一个 Key 和一个 Value。操作只有 get 和 put,如下:

    get(key);
    
    
    put(key, value);
    

    从最简单的开始,每个数据库一个data.db文件,我们像写日志一样,将每条记录 append 到文件结尾。

    key1,value1
    key2,value2
    key3,value3
    key10,value10
    key8,value8
    

    这样我们已经完成了 80%了,然后需要完成读功能。如上数据文件,若需要查询 key2 数据,我们只能从文件开头开始遍历,当直到读取到 key2 数据:

    for (row in rows) {
       if (row.key == "key1") {
          return row;
       }
    }
    

    好了,一个简单的数据库就完成了。

    什么?完成了?是的,完成了,虽然说拿出去会被砍死,但谁也不能否认它已经完成了一个数据库系统的最基本功能。

    **这样的遍历是十分耗费性能的。**那么怎么提高读取性能呢?创建一个内存索引“Index”即可,最简单的方式,在内存中维护一个 Map,存储每个 key 对应的文件内容偏移量。这样读取一条记录就只需要一次内存操作加上一次磁盘操作就可以了。

    b-tree 是因何出现的?想一想上面的 Map 结构的索引有什么缺点?Map 索引解决了随机单点读的性能问题,但无法解决 Rang 查询,比如需要查询 key 在 key1 和 key200 之间的数据。于是,就有了 b-tree,b 树是有序的结构树,可以很简单的进行 Rang 查询。

    b-tree 将所有数据都索引在内存中,当数据无限增长时,将无法在内存中存放这么大的索引文件。

    我们来看看 LSM 的实现。

    LSM 架构

    SSTable:LSM 的磁盘文件,称作SSTable(Sorted String Table)。望文得意,LSM 存储在磁盘中的文件,数据也是按 Key 排序存储的,这样就可以解决上面讲到的数据量大了之后无法将数据全部索引到内存中的问题。如果磁盘文件也是有序的,那么内存索引可以采取”稀疏索引“(Sparse Index),可以每一段记录一个索引,将数据逻辑上分成多个block,稀疏索引只需要记录每个block的偏移量,每条数据通过遍历block实现。这样索引量将大大减小。

    Memtable:LSM 的内存结构叫做MemtableMemtable是一个有序结构,同样可以采用树结构,可以用跳表。LSM 写数据时,只需要写入内存中的Memtable,当Memtable到达一定量之后,会异步刷入磁盘,就是上面的SSTable

    immutable Memtable:在数据从内存Memtable刷入SSTable时,为避免读写锁导致的性能问题,LSM 会在内存中 copy 一份immutable Memtable表,顾名思义,这个数据结构不可改变,新写入的数据只会写入新的Memtableimmutable Memtable供刷盘线程读取,查询数据的请求也可以访问这个数据结构,这样如果数据在内存中,就不需要访问磁盘,可以提供数据查询的效率。

    **WAL:**write ahead log,预写日志,关于 WAL,可以参考我之前的文章《你常听说的 WAL 到底是什么》。在 LSM 中,在数据刷入磁盘前,为防止异常导致数据丢失,LSM 会先将数据写入 WAL,然后写入 SSTable,系统重启时,LSM 会从 WAL 中回溯 SSTable,当写完一个 SSTable 时,LSM 会清理掉过期的 WAL 日志,防止 WAL 过量。

    LSM 写

    LSM 的写包括四个流程:

    1. 写入 WAL

    2. 写入 memtable

    3. memtable 达到阈值时,复制 imutable memtable

    4. 异步刷入磁盘

    LSM 删除

    为保证顺序写磁盘,LSM 不会去直接删除数据,而是通过写一条 delete 标识来表示数据被删除,数据只有在被 Compact 时才会被真正删除。

    LSM 读

    LSM 读取数据将从memtableimutablesstable依次读取,直到读取到数据或读完所有层次的数据结构返回无数据。所以当数据不存在时,需要依次读取各层文件。LSM 可以通过引入布隆过滤器来先判断一个数据是否存在,避免无效的扫文件。

    LSM 合并

    LSM 的合并策略是 LSM 很重要的一个部分,我们将放在下一篇文章中单独讲解。

    LSM 结构的应用十分广泛,诸如Bigtable,HBase,LevelDB,SQLite4, Tarantool , RocksDB,WiredTiger ,Apache Cassandra,InfluxDB 底层都使用了 LSM。只好的文章,我们将详细讲解 LSM 在 leveldb 或 Cassandra 中的实现。

    推荐:

    Mysql 大表问题和解决
    Mysql 主键问题
    列式存储
    时间序列数据库(TSDB)初识与选择
    十分钟了解 Apache Druid
    Apache Druid 底层存储设计
    Apache Druid 的集群设计与工作流程

    码哥字节
    展开全文
  • LSM Tree

    2020-06-13 14:29:44
    并且这也是一非常经典的数据结构,并且在大数据系统当中有非常广泛的应用。有许多耳熟能详的经典系统,底层就是基于LSM树实现的。因此,今天就和大家一起来深入学习一下它的原理。 背景知识 首先,我们先从背景...
  • 关于LSM

    2020-07-09 09:37:30
    其实它并不属于一具体的数据结构,它更是一种数据结构的设计思想。大多NoSQL数据库核心思想都是基于LSM来做的,只是具体的实现不同。所以本来不打算列入该系列,但是有朋友留言了好几次让我讲LSM树,那么就说...
  • 如题,一简单的基于LSM的沙箱设计。环境是Linux v4.4.28。一比较新的版本,所以在实现过程中很难找到资料,而且还有各种坑逼,所以大部分的时间都是在看源码,虽然写的很烂,但是感觉收获还是挺大的。 具体思路...
  • LSM树学习

    千次阅读 2018-11-02 21:28:52
    LSM树存储模型 关于Mem Table、Immutable Mem Table和SSTable等概念见博客: https://blog.csdn.net/qq910894904/article/details/38014127 LSM的基本思想是将修改的数据保存在内存,达到一定数量后在将修改的...
  • LSM算法原理

    千次阅读 2017-04-08 22:34:13
    十年前,谷歌发表了 “BigTable” 的论文,论文中很很酷的方面之一就是它所使用的文件组织方式,这方法更一般的名字叫 Log Structured-Merge Tree。 LSM是当前被用在许多产品的文件结构策略:HBase, Cassandra,...
  • LSM框架介绍

    千次阅读 2019-04-18 11:17:44
    LSM是Linux Security Module的简写 在内核需要安全检查的地方安插了很钩子: //所有的钩子都定义在security/security.c文件中 int security_file_open(struct file *file, const struct cred *cred) { int ...
  • HBase LSM

    千次阅读 2016-06-01 18:02:02
    HBase文件系统LSM数据结构的主题思想与特点
  • LSM树详解

    2021-01-07 21:23:24
    LSM树(Log-Structured-Merge-Tree)的名字往往会给初识者一错误的印象,事实上,LSM树并不像B+树、红黑树一样是一颗严格的树状数据结构,它其实是一种存储结构,目前HBase,LevelDB,RocksDB这些NoSQL存储都是采用的...
  • LSM6dsl.zip

    2020-03-26 11:04:15
    陀螺仪的应用越来越lsm6dsl在功耗,体积和性能方面都很出色,其实我们都习惯漫天找资料,其实有这两文档就够了。
  • LSM-Tree

    2020-11-20 14:44:08
    (这是我自己的blog~) 内容是自己拼接的,非原创,侵删 特点 总的来说就是通过将大量的随机写转换...这里有一篇比较B树,B+树,以及lsm树的文章。 存储模型 WAL(write ahead log)也称预写log,包括mysql的Binlog等.
  • lsm-tree

    千次阅读 2013-10-10 10:42:57
    http://blog.sina.com.cn/s/blog_693f08470101njc7.html ... 总结:lsm-tree就是在内存中用多个树缓存数据的更新,当内存满时,在将多个树进行合并,写入磁盘。 今天来聊聊lsm tree,它的全称是log
  • LSM存储引擎

    2021-05-31 11:47:40
    LSM(log structured merge Trees)是一种存储引擎,存储引擎有两最基本的操作就是读和写。LSM之所以出现的根本原因就在于磁盘的顺序读写性能远远高于随机读写。 问题 对于存储引擎来说,如果只是写而不考虑读的话就...
  • LSM-tree

    2020-04-11 21:23:10
    组成:两类似于树的结构:C0和C1,分别在主存中(memery)和磁盘中(disk)。 对于快速写入,传入的KV记录被插入到C0中,只访问主存。当C0在主存中充满时,它的部分与磁盘中的C1合并,在主存中为新数据留下空间。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,644
精华内容 3,857
关键字:

多个lsm