这是我参与「第四届青训营 」笔记创作活动的第25天
概念与历史
历史
Log-Structured Merge-Tree,日志结构合并树。
LSMT是由Patrick O 'Neil etc.在 1996 年的论文,The Log-Structured Merge-Tree (LSM-Tree),提出
相较而言,B-Tree出现就早得多了,在1970年由 Bayer,R.; McCreight,E.提出
早期的数据库系统一般都采用B-Tree家族作为索引,例如MySQL。2000年后诞生的数据库大多采用LSMT索引,例如Google BigTable,HBase,Canssandra 等
概念与核心思想
简单来讲,LSM tree设计的目的是超越B+树或者ISAM方式,提供更高的写吞吐率。为了达到该目标,算法摒弃了分散的,原地更新的操作
简单来说就是增量备份的思想,不再覆盖原有值,再用另外一份空间去存储 key 对应的新 value,读取的时候 merge on read,牺牲少量的读性能换取巨大的写性能,我记得这玩意在列式存储引擎中也提到过。
HHD是早期机械硬盘,他的特性是任何顺序读写,效率远高于随机读写。SSD是现代固态硬盘,他的特性是顺序读与随机读性能差异不大,顺序写效率远高于随机写。因此,如何处理随机写问题,或者说如何规避随机写问题,就会变成底层软件永久探讨的话题
基础思考
这里就不把那些个烦人的理念扔出来,也不把烦人的计算扔出来,毕竟很多人其实只是想要了解算法的运作流程,而不是来看让人昏昏欲睡的外国论文
首先,我们相比与B+树,得解决的第一个问题就是如何减少随机写,转换为顺序写。
一个不错的起点是,我们简单的执行文件追加 append 这种方式(常被称为日志,或者堆文件(heap file)),可以提供理论吞吐率上限的性能(典型数字是每块磁盘200~300MB/s)
弊端
上述方法足够简单,性能很好,所以在很多大数据应用中广泛使用,但是,它有一个明显的缺点,从日志中随机读取将非常耗时,涉及到按时间顺序从近及远扫描日志,直到找到查找的键(当然,如果是固态硬盘的话性能上应该不会有太大影响)
为了应对更复杂的读取范式(比如基于键的搜索,范围搜索),日志是不够的。宽泛的讲,有四种方式可以帮助我们解决问题。
- 对文件排序(基于键)。如果数据宽度一致,可以使用二分查找。如果不是,可以使用索引加扫描。
- 哈希。使用哈希函数将数据打散进入buckets,之后就可以直接读取。
- B+树。使用有助于导航的文件组织,比如B+树,ISAM等
- 外部文件。数据就是一个日志形式,另外单独创建哈希或者索引。
LSMT实现
- 不采用单一的大索引结构,写操作被批量顺序地存储在一系列小索引文件中
- 每个文件在存储之前都会排序,使得之后的搜索很快
- 文件是不可变的,文件绝不会被更新
- 新的更新会写入新的文件
- 读操作检查所有文件
- 文件周期性地被归并到一起,以保持文件数目不会爆炸
大致了解这些特征就可以满足一般人的求知欲了
(好吧,实际上是我自己都没听懂,大致听了,然后查了查资料,然后得到了答案)
\