LSM树存储模型

LSM(log-structed-merge-tree)

leveldb和rocksdb底层使用LSM树做存储引擎,LSM树使用skiplist做索引,他们先将数据写入内存中,按照key进行划分,定期的merge写入到磁盘中,合并后数据写入下一层level

LSM是什么?解决什么问题?
在leveldb和rocksdb中,面临的一个主要问题是数据的落盘,在写磁盘时,随机写会消耗很大的磁盘IO,因此为了解决随机写的问题,引入了LSM树。LSM树将随机写变成了append,极大地降低了磁盘IO的消耗。

 

MySQL的innodb引擎使用了B+树作为索引

B+树作为索引时,随机读很快,但是有大量的随机写时,会占用很多的磁盘IO导致消耗比较大。B+树是通过降低树的高度,使树的分叉尽可能多来达到查询时的高效率的。但是在update、insert或delete时,需要进行树的调整,因此磁盘IO的消耗会比较大。所以说B+树不适合作为leveldb和rocksdb的存储引擎。

例如:假设要写入一个100000个随机的key,对磁盘来说,最快的写入方式一定是顺序地将每一次写入都直接写入到磁盘中即可。
但这样带来的问题是查询消耗大量的磁盘IO,因为每次查询一个值都需要遍历整个数据才能找到,这个读性能就太差了;
那么如果我想获取磁盘读性能最高,应该怎么做呢?把数据全部排序就行了,B+树就是这样的结构,但B+树的写性能太差了,需要提升写,可以放弃部分磁盘读性能,怎么办呢? 引入LSM树

LSM是如何解决问题的?

LSM树将随机写变成了append,降低了磁盘IO的消耗,但是以牺牲部分读性能达到优化写性能的目的。

将有序的分组数据划分很多个小的有序结构,比如每m个数据,在内存里排序一次,下面100个数据,再排序一次……这样依次做下去,我就可以获得N/m个有序的小的有序结构,在查询的时候,因为不知道这个数据到底是在哪里,所以就从最新的一个小的有序结构里做二分查找,找得到就返回,找不到就继续找下一个小有序结构,一直到找到为止。

因此,LSM树读取的时间复杂度是(N/m)*log2N,读取效率是会下降的,这就是LSM的根本思路。

为了降低读时磁盘IO的消耗,leveldb和rocksdb引入了bloom filter和compact机制。

 

LSM树是以牺牲读的效率来达到提升随机写效率的目的。

你可能感兴趣的:(C++,数据库,数据结构)