LSMT数据存储 | 青训营笔记

113 阅读3分钟

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

起源:BTree是1970年提出的,LSMT是1996年提出的。所以早起数据库都是B+Tree索引,新的数据库都是LSMT存储引擎,如 TiDB,CockroachDB,HBase,Canssandra,RocksDB 等

工作原理:通过Append-only Write + 择机Compact来维护结构的索引树

LSMT 存储引擎

存储引擎是什么?

传统数据库大致可以分为

  • 计算层:负责SQL解析、查询优化、计划执行

  • 存储层(存储引擎层):

    • 数据库著名的ACID特性,在单机中都强依赖于存储引擎
    • 屏蔽 IO 细节提供更好的抽象
    • 提供统计信息与 Predicate Push Down 能力

子结构

  • SSTable:全称是Stored String Table,本质上就是一个KV结构的顺序排列的文件。如下图:

    在这里插入图片描述

    • SSTable是不可修改的,只会用新的SSTable来覆盖旧的
  • MemTable:存放在内存中的数据结构,可以快速实现增删改查,比如红黑树,Skiplist都行

  • log文件,记录数据发生的变化,用于服务器宕机时找回数据

整体架构

image-20220815103542693

LSMT 与 B+Tree 的异同

  • B+树,数据的插入是原地更新的,在发生不平衡或者节点容量到达阈值后,必须立即进行分裂来平衡
  • 工程实践上用LSMT表示一个Append-only 和Lazy Compact的索引树,B+ Tree表示一个Inplace-Update和Instance Compact的索引树
  • LSMT 与 B+Tree 可以用统一模型描述并且相互转化

LSMT 存储引擎的优势

  • 顺序写模型对于 SSD 设备更友好
  • SST 不可修改的特性使得其能使用更加紧凑的数据排列和加上压缩
  • 后台延迟 Compact 能更好利用 CPU 多核处理能力,降低前台请求延迟

顺序与随机操作性能不对称,顺序写吞吐是随机性能的好几倍。顺序写是一个对设备很友好的操作,LSMT符合这一点,但是B+Tree依赖原地更新,导致随机写

  • LSMT的存储引擎的顺序写特性更适合现代计算机体系结构

LSMT实现和优化

HBase实现

HBase中的SST 直接存储于 HDFS 上,Meta 信息 RocksDB 自己管理维护于 Manifest 文件,HBase 放置于 ZK。

RocksDB实现

image.png

  1. 批量WAL写入,多个writer选leader一次性写WAL

    • 好处:可以批量聚合请求,避免频繁提交小 IO
    • WAL不必须落盘,提交到kernel的页缓存就可。Kernel自身的聚合io再下刷能够降低了操作系统调度线程的开销。
  2. 并发MemTable更新,WAL一次性写入之后唤醒其他writer进行并行写入。最后一个完成的进行收尾工作

优化

  • superVersion:拥有MemTable/ImmemTable/ssT三部分数据并且提供快照功能的组件

    • 为了让渡操作有更好的规模,进行Thread Local SuperVersion
    • 有了Thread Local 缓存,读取只需要检查SuperVersion并标记缓存正在被使用即可,对cpu缓存友好
  • BloomFilter:加速查找,在SST中嵌入 BloomFilter

  • Compact:将Key区间有重叠或者无效数据较多的SST进行合并,一次来加速读取或者回收空间

    • Level:每一个层不允许有SST的key区间重合

      • 增加了写放大,降低了读和空间放大。
    • Tier:每一个层允许有SST的key区间重合

      • 策略:用读放大的增加换取了写放大的减小。

\