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

955 阅读7分钟

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

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

一、课程概述

  • 介绍LSMT存储引擎的背景、优势与实现
  • 介绍LSMT等模型理论
  • 介绍LSMT存储引擎调优

二、详细内容

1. LSMT存储引擎

1.1 LSMT的历史

  • LSMT是log-structured merge-tree的缩写
  • 相较而言B-Tree早得多
  • 早起数据库一般采用B-Tree,近期则是LSMT为多

1.2 LSMT基础

  • Append-only write+择机compact来维护结构的索引树
  • manifest log传输给write-ahead-log WAL
  • 写入memtable
  • 当memtable满后 flush进L0 cache生成SST file
  • compaction(merge sort,remove)

1.3 存储引擎是什么

  • 单机数据库MySQL大致分为计算层和存储层
    • 计算层负责SQL解析、查询优化、计划执行
    • 数据库ACID特性强依赖于存储引擎
      • Atomicity原子性:依赖于WAL/Redo Log
      • Consistency(correctness):依赖于数据库整体
      • Isolation:存储引擎snapshot/2-phase-lock
      • Durability:flusher遵循sync语义
  • 此外存储引擎还要负责
    • 屏蔽IO细节提供更好抽象
      • 存储引擎不掌控IO细节,操作系统接管,例如使用mmap的问题:
        • 落盘时机不确定造成事务不安全
        • IO stall:用户态程序无法插手,不可控
        • 错误处理繁琐:硬件错误用户无法获知,需要完整性校验
        • 无法完全发挥硬件性能:要切换到内核态
    • 提供统计信息与predicate push down能力:parquet只需要部分column时下推给存储引擎读取部分即可

2.LSMT的优势和实现

2.1 LSMT与B+树存储

  • 在B+树中数据插入原地更新
  • B+树不平衡或节点容量阈值后必须立即分裂来平衡
  • LSMT与B+树统一模型,二者可以互相转化
    • LSMT表示append-only和lazy compact的索引树
    • B+树表示inplace-update和instant compact的索引树
  • append-only和lazy compact更符合现代计算机设备特性

2.2 为何要采用LSMT模型

  • 计算机存储/工程界使用indirection处理资源的不对称性
  • 存储引擎面对的资源不对称性在不同时期不同
    • HDD时代:顺序与随机操作性能不对称;机械硬盘需要磁盘旋转和机械臂移动进行读写,顺序写吞吐是随机读的25倍;
    • SSD时代:顺序写与随机写性能不对称;由于SSD随机写会对主控带来GC压力,顺序写吞吐是随机写6倍;
  • 顺序写对设备友好,LSMT符合顺序写;B+树依赖原地更新导致大量随机写(不友好)

2.3 LSMT存储引擎实现,以RocksDB为例

2.3.1 RocksDB写实现

  • WAL
    • 需要写WAL(重启时可以保证原子性),多个写入者选出一个Leader,由Leader一次性写入WAL,避免小IO;写完后唤醒所有writer
    • 不要求WAL强制落盘(sync)时,批量提交亦有好处;没有批量提交时只能链式唤醒,加大前台延迟
  • MemTable
    • 在LevelDB基础上添加并发Memtable写入优化
    • WAL一次性写入完成后唤醒所有writer并行写入MemTable
    • 由最后一个完成MemTable写入的writer执行收尾工作(退出write group)

2.3.2 RocksDB snapshot和supervision

  • 数据由MemTable/ImmemTable/SST组成,持有三部分数据并且提供快照功能的组件叫做supervision
  • MemTable和SST释放依赖于引用计数,对于读取只要有supervision从memtable一级一级向下就能查到记录;拿着supervision不释放等于拿到快照。
  • 如果所有读者给supervision计数+1读完-1,原子引用计算器成为热点;使用了thread local cache
    • 没有时,读取频繁获取和释放supervision,对CPU缓存不友好
    • 使用thread local cache缓存,只需要检查supervision的version没过期,并标记thread local cache正在使用即可;对CPU缓存友好
    • 若superversion过期需要重新生成,当更新时需要标记所有人持有的superversion失效

2.3.3 RocksDB Get和BloomFilter

  • 读取上和B+树类似,层层向下
    • LSMT点查需要访问的数据块更多,加速点查一般LSTM会在SST中引用BloomFilter
    • BloomFilter可以保证数据不在该块中,但只能大概率保证数据在该块中

2.3.4 Compact

  • Compact在LSTM中将Key区间有重叠或无效数据较多的SST进行合并以此加速读取或回收空间
    • 策略:Level和Tier
  • Level 策略来自于LevelDB,每层不允许SST的key区间重合
    • 例如用户写0-100 SST,和原有0-100SST merge形成一个新的0-100的大SST(小SST和大SST合并)
    • 写放大问题/不平均
  • Tier策略允许LSMT每层有多个区间重合的SST
    • 当本层重合SST区间或总内存大小到达上限,选择多个重合SST向下推形成新的SST
    • 理论上每层SST区间大小接近,merge效率高
    • 读放大增加换取写放大减小:更多重合SST需要更多读取

3. LSTM理论分析

3.1 HBase:cloud-native

3.2 LSMT模型算法复杂度分析

  • T:size ratio即每层比上层大多少,L0为1,L1为T...
  • L:level num,LSMT层数
  • B:每个最小IO单位能装载多少记录
  • M:每个BloomFilter有多少Bits
  • N:每个BloomFilter生成用了多少key
  • S:区间查询的记录数量
  • e^(-M/N):bloom filter失效率

3.2.1 Level

  • 写操作
    • 每条记录需要经过L次Compact,每次Compact Ln的一个小SST和Ln+1的大SST
    • 设小SST大小为1,大SST为T,合并1+T,单次写放大为T
    • 每条记录写入成本为1/B次最小单位IO
    • O(write_level)= L*T*1/B = T*L/B
  • point lookup
    • 每条key最多L个重叠区间
    • bloom filter失效率为e^(-M/N),失效时访问下一层
    • O(pointLookup_level)=L*e^(-M/N)
    • 不乘1/B因为写入可以批量提交拉低成本,但读取时必须对其最小读取单元尺寸

3.2.2 Tier

  • 写操作
    • 每条记录需要经过L次Compact,每次Compact Ln中T个相同尺寸的SST到Ln+1
    • SST大小为1,T个合并开销为T;
    • 将T单位Ln SST推到Ln+1需要T的IO,单次写放大为1
    • 每条记录写入成本为1/B次最小单位IO
    • O(write_level)= L*1*1/B = L/B
  • point lookup
    • 每条key有L层
    • 每层最多有T个重叠区间SST,对于整体来说有T*L个可能命中的SST
    • bloom filter失效率为e^(-M/N),失效时访问下一层
    • O(pointLookup_level)=T*L*e^(-M/N)
    • 不乘1/B因为写入可以批量提交拉低成本,但读取时必须对其最小读取单元尺寸

3.2.3 其他复杂度

  • Short Range Scan复杂度:level-O(L);Tier-O(T*L)
  • space amplification复杂度: level-上层都是垃圾 O(T+1/T);Tier:O(T)

3.2.4 总结

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

4. 实例

4.1 TerarkDB

  • KV分离:分为value不同长度;value长的记录单独存储(避免compaction频繁挪动)
  • 小key大value,写多读少,延迟大幅度降低,长尾消失,可以接受比rocksDB高50%负载
  • Flink流处理状态存储
    • 平均CPU开销降低26%~39%
    • 峰值CPU开销降低67%
    • 平均容量降低17%~31.2%

4.2 发展趋势

  • 新硬件
    • 新存储技术:SMR HDD/Zoned SSD/OpenChannel SSD,PMem
    • 如何在新硬件上设计/改进存储引擎是热点
    • L0->PMem降低写放大
  • 新模型
    • LSMT不能应对所有工况
    • WiscKey通过额外增加value store存储大value记录降低总体写放大
    • REMIX
  • 新参数/新工况
    • 在现有模型工况下进行参数调残
    • LSMB在最后层使用level,上层tier,通过在最后一层外SST加大bloomFilter的bits数规避Tier Compaction带来的点查劣化

三、个人总结

这节课学习了LSMT存储引擎的背景、优势、理论与实现,及其调优的过程。由于我没有接触过相关算法,进一步比对B+树学习相关算法是非常必要的。