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

59 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第14天

LSMT(Log-Structured Merge-Tree)

早期的数据库系统一般都采用B-Tree家族作为索引,例如MySQL。2000年后诞生的数据库大多采用LSMT索引,例如Google BigTable,HBase , Canssandra等。

LSMT是通过Append-only Write + 择机Compact来维护结构的索引树。

存储引擎

以单机数据库MySQL为例,大致可以分为

  • 计算层
  • 存储层(存储引擎层)

计算层主要负责 SQL 解析/ 查询优化 / 计划执行。数据库著名的 ACID 特性,在 MySQL 中全部强依赖于存储引擎。

1)存储引擎要保障ACID

  • Atomicity(要求一个事务的所有变更要么全部成功,要么全部失败,不存在中间状态): 这个特性依赖于存储引擎的Write-Ahead Log(WAL)/ Redo Log。程序 crash 了后,在重启阶段可以通过回放 WAL 来恢复或者继续之前的变更, 这样子操作就只有成功和失败两种状态。
  • Consistency: 依赖于包括存储引擎在内的数据库整体
  • Isolation(要求多个事务不会互相影响): 依赖于存储引擎提供的快照能力,即Snapshot / 2PL(2 Phase Lock,对所有需要修改的资源进行上锁,避免冲突)。
  • Durability(持久性,保证数据不丢): 依赖于存储引擎在事务提交之后,通过操作系统的接口确认数据落盘(Sync),确保重启或断电之后依然能读到数据。 Flusher遵循Sync语意。

2)除了保障ACID 以外,存储引擎还要负责:

  • 屏蔽IO细节提供更好的抽象。

  • 提供统计信息与Predicate Push Down能力(可以简单理解为一种过滤的能力)

存储引擎不掌控IO细节,让操作系统屏蔽,例如使用mmap接口,由于操作系统并不完全感知数据库任务的特性,会有如下问题︰

1.落盘时机不确定导致事务不安全:因为操作系统并不知道具体的事务 commit 时机,有可能事务还没 commit,但数据已经落盘了

2.IO Stall:mmap 在发生 page fault 的时候,用户态程序是没办法插手的,也没办法预期什么时候完成,不可控

3.错误处理繁琐:mmap 在发生硬件错误的时候,并没有办法通知用户状态,每次读取都要进行数据的完整性校验

4.无法完全发挥硬件性能,mmap 触发 page fault 的成本很高,必须切换到内核态,无法完全发挥硬件性能

LSMT存储引擎的优势与实现

1.LSMT 与B+Tree的异同

1)异

  • 在B+Tree 中,数据插入是原地更新的。
  • B+Tree在发生不平衡或者节点容量到达阈值后,必须立即进行分裂来平衡
  • 在 LSMT,数据的插入是追加的(Append-only),当树不平衡或者垃圾过多时,有专门 Compact 线程进行 Compact,可以称之为延迟(Lazy)的。

2)同

  • LSMT与B+Tree可以用统—模型描述
  • 从高层次的数据结构角度来看,二者没有本质的不同,可以互相转化

2.为什么要采用 LSMT模型

1)LSMT符合顺序写

  1. 资源不对称性
  • 在计算机存储乃至整个工程界都在利用Indirection处理资源的不对称性
  • 存储引擎面对的资源不对称性在不同时期是不同的

2.顺序写 vs 随机写

HDD时代

顺序与随机操作性能不对称

机械硬盘的读写依赖于磁盘的旋转和机械臂移动来进行读写,顺序写吞吐的能力是随机读的25倍。

SSD时代

顺序写与随机写性能不对称

由于SSD随机写会给主控带来GC压力,顺序写吞吐的能力是随机写的6倍。

3.小结︰ 这二者的共性是顺序写是一个对设备很友好的操作,LSMT符合这一点,而 B+Tree依赖原地 更新,导致随机写。

  • HDD时代,顺序操作远快于随机操作
  • SSD时代,顺序写操作远快于随机写操作

Cloud-Native LSMT Storage Engine --- HBase

RocksDB 是单机存储引擎,那么现在都说云原生,HBase 比 RocksDB 就更「云」一些,SST 直接存储于 HDFS 上,二者在理论存储模型上都是 LSMT。

LSMT模型理论分析

  • Level 策略增加了写放大,降低了读和空间放大
  • Tier 策略降低了写放大,增加了读放大和空间放大

总结

  • 单机数据库的ACID特性依赖于存储引擎
  • LSMT存储引擎的顺序写特性更适合现代计算机体系结构
  • LSMT和B+Tree可以用同一模型描述并互相转化
  • Level Compaction策略,降低了读放大和空间放大,增加了写放大
  • Tier Compaction策略,降低了写放大,增大了读放大和空间放大
  • 分布式KV存储,如HBase,背后的理论模型与单机存储引擎RocksDB一样都是LSMT