与传统LSMTree结构的异同 | OceanBase 存储引擎技术原理(二)
上一篇博文描绘了OceanBase存储架构到自然界"水生态"的一个映射关系,今天让我们换个角度,与同样是LSM-Tree结构的其他产品进行比较,一起来看看相比之下OceanBase都有哪些独特之处。
我们都知道,OceanBase 数据库的存储引擎基于 LSM-Tree 架构,相比于OceanBase的LSM-Tree实现,传统LSM-Tree结构通常具有更明显的层次化存储。我们以业界经典的LSM-Tree实现--单机存储引擎LevelDB为例,其数据流向和OceanBase数据库是类似的,数据会从可写的Activate Memtable->只读的Immutable Memtable->L 0 ->L 1 ->...->L n 。磁盘数据被从上到下分成了多个层次,越下层的数据越旧。此外,数据在写入内存前会先追加写入写前日志(WAL)中。
LevelDB中只读的内存数据通过Flush过程被下刷到磁盘,并按照键的顺序以SSTable文件的形式存储。L0层的SSTable文件间存在数据范围的重叠,每个SSTable文件可以被认为是一个sorted run(一个有序的集合,集合内每个元素唯一)。而L0层以下的每一层SSTable文件是有序不重叠的,也就是说,每一层的多个SSTable文件共同构成了一个sorted run。每层的SSTable文件会通过compact过程向下一层移动,每一次compact过程会涉及到相邻两层多个数据范围重叠的SSTable文件。这些SSTable文件的数据会重新进行排序与合并,形成一个新的SSTable文件。随着从上到下层数的增加,每层的可容纳SSTable文件总数据量会成倍数增长。
对于这样的分层结构,我们很容易注意到其中存在的几个问题:
- 读放大
- LSM-Tree的读操作需要从新到旧层层查找,这个过程可能需要多次I/O,放大了读盘次数。
- 空间放大
- 磁盘数据都是只读的,大量冗余和无效数据会占用额外的存储,放大了磁盘空间。
- 写放大
- 磁盘数据的有序整理不可避免的带来了额外的写入。