LSM树 与B+树比较

现在假设有 1000 个节点的key。对于磁盘,一定是将这1000个节点依次写入磁盘的速度最快。但是这样读很糟糕,因为key在磁盘中完全乱了,每次读都得扫描。

那么,为了使读取性能尽可能高,磁盘中的数据必须是有序的。这就是B+树的原理,但是写起来就很糟糕,因为会产生大量的随机IO,磁盘寻道速度跟不上。

关于b树

B+树最大的性能问题是会产生大量的随机io。随着新数据的插入,叶子节点会慢慢分裂。逻辑上连续的叶节点通常在物理上不连续,甚至相距很远。在做范围查询的时候,会产生大量的读取随机io。

对于大量的随机写入,同样如此。比如insert key跨度很大,7 -> 1000 -> 3 -> 2000... 新插入的数据存储在磁盘上,会产生大量的随机写IO。

例如,Oracle 的常用索引使用 B+ 树。下面是一个B+树的例子

5f20291f1186cbaf2d2894e4c069ff76.png


根节点和分支节点很简单,记录每个叶子节点的最小值,用指针指向叶子节点。

叶节点中的每个键值都指向真实的数据块(如Oracle中的ROWID),每个叶节点都有一个前继指针和一个后继指针。这是为了在做范围查询时,在叶子节点之间直接跳转,避免回溯到分支和后续节点。

关于lsm树

LSM 树本质上是读写之间的平衡。与B+树相比,它牺牲了部分读取性能来提高写入性能。

其原理是将一棵大树分裂成n棵小树,先写入内存(不存在内存中的seek速度问题,所以随机写入的性能大大提高)。在内存中构建了一个有序的小树。随着小树越来越大,内存中的小树会被刷新到磁盘。读取的时候,因为我们不知道数据在哪棵树上,所以必须遍历所有的树,但是每棵树中的数据都是有序的。

4488e2aa106cdd4b7eee89db26bf433d.png

以上就是LSM树最本质的原理,有了原理,再看具体的技术就很简单了:

关于lsm内存结构,可以是B+树,还可以为跳跃表(skip-list)或是一个有序字符串表(SSTables)。

我们以跳表作为内存结构例子,leveldb,hbase都使用跳表。

7a68776e554566e543e630b637548ac1.gif

跳表SkipList,顾名思义是链表的一种,或者说它是单链表的变异实现,使用跳表可以将查询操作的复杂度控制到θ(lg N),而普通的链表只能通过顺序查找,复杂度为θ(N),如此跳表的优势就很明显了,虽然它是通过以空间换时间搞定的。

跳表通过对间隔的数据做一个标签索引,产生了多层单链表,在最高层依次确定查找数据的范围,最终将范围缩小到可接受值,我们看跳表其实就是一个二叉查找树的变形,只是所有的数据都在最左段,其他节点用来建立查找索引,如此跳表的插入删除就比二叉查找树方便多了

wal日志 首先,我想说一下为什么我们需要wal(写前日志)。很简单,因为数据是先写入内存的。如果断电,内存中的数据将会丢失。因此,为了保护内存中的数据,我们需要先将日志文件记录在磁盘上。当内存中的数据刷新到磁盘时,我们可以丢弃相应的日志文件。

什么是memstore、storefile? 这很简单。如上所述,LSM 树只是一堆小树。内存中的小树叫做memstore。每次flush时,内存中的 memstore 都会成为磁盘上的storefile。

为什么有一个compact过程? 这很简单。随着小树越来越多,读取性能会越来越差。因此,需要在适当的时候合并磁盘中的小树,多个小树将成为一棵大的树结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值