LSM存储模型

LSM存储模型

 

数据库有3种基本的存储引擎:html

  • 哈希表,支持增、删、改以及随机读取操做,但不支持顺序扫描,对应的存储系统为key-value存储系统。对于key-value的插入以及查询,哈希表的复杂度都是O(1),明显比树的操做O(n)快,若是不须要有序的遍历数据,哈希表就是不错的选择;
  • B+树,支持单条记录的增、删、读、改操做,还支持顺序扫描(B+树的叶子节点之间的指针),对应的存储系统就是关系数据库(Mysql等)。
  • LSM树(Log-Structured Merge Tree),LSM树和B树同样,一样支持增、删、读、改、顺序扫描操做,并且经过批量存储技术规避磁盘随机写入问题。固然凡事有利有弊,LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提升写性能;基于LSM树实现的数据库如LevelDB、HBase等。

 

LSM的本质是将随机写转化为顺序写,具体实现方式以下:sql

  1. 当有写操做(或update操做)时,写入位于内存的buffer,内存中经过某种数据结构(如skiplist)保持key有序;
  2. 为了防止进程忽然挂掉致使内存的数据丢失,通常会将数据追加写到磁盘Log文件后才写入buffer,以备必要时能从log恢复数据;
  3. 内存中的数据定时或按固定大小地刷到磁盘,更新操做只不断地写到内存,并不更新磁盘上已有文件;
  4. 随着愈来愈多写操做,磁盘上积累的文件也愈来愈多,这些文件不可写且有序;
  5. 定时对文件进行合并操做(compaction),消除冗余数据,减小文件数量;

 

LSM-Tree 的设计思想很是朴素:将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操做批量写入磁盘,不过读取的时候稍微麻烦,须要合并磁盘中历史数据和内存中最近修改操做,因此写入性能大大提高,读取时可能须要先看是否命中内存,不然须要访问较多的磁盘文件。所以,LSM-Tree比较适合的应用场景是:insert数据量大,读数据量和update数据量不高且读通常针对最新数据。数据库

 

LSM树原理把一棵大树拆分红N棵小树,它首先写入内存中,随着小树愈来愈大,内存中的小树会flush到磁盘中,磁盘中的树按期能够作merge操做,合并成一棵大树,以优化读性能。缓存

数据首先会插入到内存中的树。当内存中的树中的数据超过必定阈值时,会进行合并操做。合并操做会从左至右遍历内存中的树的叶子节点与磁盘中的树的叶子节点进行合并,当被合并的数据量达到磁盘的存储页的大小时,会将合并后的数据持久化到磁盘,同时更新父亲节点对叶子节点的指针。数据结构

 

 

以前存在于磁盘的叶子节点被合并后,旧的数据并不会被删除,这些数据会拷贝一份和内存中的数据一块儿顺序写到磁盘。这会操做一些空间的浪费,可是,LSM-tree提供了一些机制来回收这些空间。
磁盘中的树的非叶子节点数据也被缓存在内存中。
数据查找会首先查找内存中树,若是没有查到结果,会转而查找磁盘中的树。

有一个很显然的问题是,若是数据量过于庞大,磁盘中的树相应地也会很大,致使的后果是合并的速度会变慢。一个解决方法是创建各个层次的树,低层次的树都比上一层次的树数据集大。假设内存中的树为c0, 磁盘中的树按照层次一次为c1, c2, c3, ... ck-1, ck。合并的顺序是(c0, c1), (c1, c2)...(ck-1, ck)。

为何LSM-tree的插入很快:框架

  • 插入操做首先会做用于内存,而且内存中的树不会很大,这会很快;
  • 合并操做会顺序写入一个或多个磁盘页,这比随机写快得多;

 

 

总结:性能

LSM存储框架实现的思路较简单,其先在内存中保存数据,再定时刷到磁盘,实现顺序IO操做,经过按期合并文件减小数据冗余;文件有序,保证读取操做相对快速。优化

咱们须要结合实际的业务场景选择合适的存储实现,不存在万金油式的通用存储框架。LSM适用于写多、读相对少(或较多读取最新写入的数据,该部分数据存在内存中,不须要磁盘IO操做)的业务场景。spa

 

 

参考文档:设计

http://www.2cto.com/database/201411/350877.html

相关文章
相关标签/搜索