LSMT 存储引擎浅析|青训营笔记

151 阅读3分钟

这是我参与【第四届青训营-大数据场】笔记创作活动的第14天

LSMT 是Log-Structured Merge-Tree 的缩写,由 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等。

a02bb8df57283428ea897acd6858b42.png 存储引擎是什么?
除了保障 ACID 以外,存储引擎还要负责:

  • 屏蔽 IO 细节提供更好的抽象
  • 提供统计信息与 Predicate Push Down能力

存储引擎不掌控 IO 细节,让操作系统接管,例如使用 mmap,会有如下问题:。落盘时机不确定造成的事务不安全. IO Stall

  • 错误处理繁琐
  • 无法完全发挥硬件性能

LSMT 与B+Tree 的异同

  • LSMT 与 B+Tree 可以用统一模型描述
  • 从高层次的数据结构角度来看,二者没有本质的不同,可以互相转化
  • 工程实践上还是用 LSMT 来表示一个 Append-only 和 Lazy Compact 的索引树,B+Tree 来表示一个Inplace-Update 和 Instant Compact 的索引树。
  • Append-only 和 Lazy Compact 这两个特性更符合现代计算机设备的特性。

为什么要采用 LSMT 模型?

All problems in computer science can be solved by another level of indirection Fro

  • 在计算机存储乃至整个工程界都在利用 Indirection 处理资源的不对称性

  • 存储引擎面对的资源不对称性在不同时期是不同的

  • RocksDB 是一款十分流行的开源 LSMT 存储引擎,最早来自 Facebook(Meta),应用于 MyRocks,TiDB 等数据库。

  • 在字节内部也有 Abase,ByteKV,ByteNDB,Bytable 等用户。

  • 因此接下来将会以 RocksDB 为例子介绍 LSMT 存储引擎的经典实现。

RocksDB

  • RocksDB 写入流程主要有两个优化,批量 WAL 写入(继承自 LevelDB)与并发 MemTable更新

  • RocksDB 在真正执行修改之前会先将变更写入 WAL,WAL写成功则写入成功。

Write

  • 多个写入者会选出一个 Leader,由这个 Leader来一次性写入 WAL,避免小 IO。

  • 不要求 WAL 强制落盘(Sync)时,批量提交亦有好处,Leader 可以同时唤醒其余 Writer,降低了系统线程调度开销。

LSMT 存储引擎的实现- Snapshot & SuperVision

  • RocksDB的数据由 3 部分组成,MemTable/ImmemTable /SST。持有这三部分数据并且提供快照功能的组件叫做 SuperVersion。

  • MemTable 和 SST 的释放依赖于引用计数。

  • 对于读取来说,只要拿着 SuperVersion,从 MemTable一级一级向下,就能查到记录。

  • 如果所有读者都给 SuperVersion 的计数加 1,读完后再减 1,那么这个原子引用计数器就会成为热点。CPU 在多核之间同步缓存是有开销的,核越多开销越大。

  • 为了让读操作更好的 scale,RocksDB 做了一个优化是 Thread Local SuperVersion Cache

Get & BloomFilter

  • RocksDB 的读取在大框架上和 B+ Tree 类似,就是层层向下。
  • 相对于 B+Tree,LSMT 点查需要访问的数据块更多。为了加速点查,一般 LSMT 引擎都会在 SST 中嵌入 BloomFilter。
  • [1,10] 表示这个索引块存储数据的区间在 1-10 之间。查询 2,就是顺着标绿色的块往下。