总结:lsm-tree就是在内存中用多个树缓存数据的更新,当内存满时,在将多个树进行合并,写入磁盘。
如果是一个运行时间很长的b树,那么几乎所有的请求,都是随机io。因为磁盘块本身已经不再连续,很难保证可以顺序读取。磁盘本身是一个顺序读写快,随机读写慢的系统,
当写读比例很大的时候(写比读多),LSM树相比于B树有更好的性能。因为随着insert操作,为了维护B树结构,节点分裂。读磁盘的随机读写概率会变大,性能会逐渐减弱。而LSM,具有批量特性,存储延迟,C0为内存组件,Cn为磁盘组件(Cn可以有多个,并且是从小到大,逐个合并),当C0 size达到阀值时,才会把insert批量刷新到磁盘。多次单页随机写,变成一次多页随机写。复用了磁盘寻道时间,极大提升效率。(C0和Cn都是有序树,查询效率为logN)
平衡树,可以看到基本上一个元素下只有两个子叶节点
抽象的来看,树想要达成有效查找,势必需要维持如下一种结构:
树的子叶节点中,左子树一定小于等于当前节点,而当前节点的右子树则一定大于当前节点。只有这样,才能够维持全局有序,才能够进行查询。
这也就决定了只有取得某一个子叶节点后,才能够根据这个节点知道他的子树的具体的值情况。这点非常之重要,因为二叉平衡树,只有两个子叶节点,所以如果想找到某个数据,他必须重复更多次“拿到一个节点的两个子节点,判断大小,再从其中一个子节点取出他的两个子节点,判断大小。”这一过程。
这个过程重复的次数,就是树的高度。那么既然每个子树只有两个节点,那么N个数据的树的高度也就很容易可以算出了。
平衡二叉树这种结构的好处是,没有空间浪费,不会存在空余的空间,但坏处是需要取出多个节点,且无法预测下一个节点的位置。这种取出的操作,在内存内进行的时候,速度很快,但如果到磁盘,那么就意味着大量随机寻道。基本磁盘就被查死了。
而b树,因为其构建过程中引入了有序数组,从而有效的降低了树的高度,一次取出一个连续的数组,这个操作在磁盘上比取出与数组相同数量的离散数据,要便宜的多。因此磁盘上基本都是b树结构。
不过,b树结构也不是完美的,与二叉树相比,他会耗费更多的空间。在最恶劣的情况下,要有几乎是元数据两倍的格子才能装得下整个数据集(当树的所有节点都进行了分裂后)。
(索引通常是非常大的,不能全部放入内存,对于二叉树而言,最极端的情况是,节点分布的很散,所以每次读取节点都要进行一次随机的磁盘读取。而对于B树而言,每个节点都存放一个有序数组,这个数组往往比较大,这样的话,树的高度就大大降低,通常可以看做高度为2,这样在查询的时候只需要磁盘读取2次,一次读取一个数组)
B树的缺点是:
1. 会占用更多的空间
2. 但如果有更新插入删除等综合写入,最后因为需要循环利用磁盘块,所以会出现较多的随机io.大量时间消耗在磁盘寻道时间上。
如果是一个运行时间很长的b树,那么几乎所有的请求,都是随机io。因为磁盘块本身已经不再连续,很难保证可以顺序读取。