LSM-Tree 概念解析

LSM-Tree全称Log Structured Merge Tree,是一种分层、有序、面向磁盘的数据结构,其核心思想是充分利用磁盘的顺序写性能要远高于随机写性能这一特性,将批量的随机写转换为一次性的顺序写。

LSM-Tree的写入操作,类似于普通的日志写入方式,以Append的模式追加;删除操作Append一条删除的日志;修改操作Append一条新key-value。

LSM-Tree非就地更新

数据的更新策略:

  • 就地更新:直接覆盖旧记录以存储更新,比如B+Tree,通常读多写少;
  • 非就地更新:将更新动作写入一条新的记录,而不是覆盖旧条目,比如LSM-Tree,通常写多读少;

    • 利用顺序I/O处理写操作,写性能较高;
    • 查找操作需要顺序按层遍历,读性能较弱;

LSM-Tree 概念解析_第1张图片

LSM-Tree组成部分

LSM-Tree有内存组件和硬盘组件两部分。
内存组件:包含Memtable和Immutable MemTable,通常使用skip-list或B+树结构

  • Memtable:数据直接写入MemTable;
  • Immutable MemTable: 不可写,被冻结的MemTable,待被合并到硬盘;

硬盘组件:包含不同Level的SSTable(sorted string table)

  • Level越低,数据越新,容量越少;反之Level越高,数据越旧,容量越大;
  • 低Level的SSTable被合并到高Level的SSTable,合并过程中会做删除操作(相同key删除旧值保留新值);
  • SSTable中除了数据块,还含有索引块,便于块内数据的快速查找;

LSM-Tree 概念解析_第2张图片

MemTable

MemTable提供了k-v数据的写入、读取和删除接口。
按key顺序存储,以便被合并到SSTable后仍然有序。

Immutable MemTable

由于内存有限,当MemTable达到一定阈值后,将其冻结成Immutable MemTable,并生成新的MemTable。
Immutable MemTable的内容达到一定阈值后,将其合并到SSTable。
使用Immutable MemTable的原因:若直接使用MemTable,MemTable被合并到SSTable过程中,会阻塞用户的写操作。

WAL

WAL(Write-Ahead-Log)预写日志,用于保证宕机时数据不丢失。
写入数据时,同时写入MemTable和WAL;由于WAL是顺序写,速度很快。
当程序宕机时,可以从WAL恢复数据到MemTable。

SSTable

SSTable(sorted string table)是Immutable MemTable在磁盘上的存储,内部按key顺序排列。
为了加快SSTable的查询速度,在SSTable中增加索引信息(如下图),可以快速定位key并查到其value。

image.png

SSTable是分层结构,Immutable Memtable达到阈值后被合并进L0的SSTable,L0的SSTable达到阈值后,会和L1的SSTable合并;由于SSTable是有序时,SSTable的合并相当于归并操作,速度很快。

LSM-Tree SSTable合并策略

磁盘中低Level的SSTable被合并到高Level中,合并过程中,可以做删除操作,降低磁盘使用,比如L0中foo=b,L1中foo=a,由于L0是更新的数据,故合并后foo=b,同时删掉L1中foo=a的记录。
SSTable有两种合并策略:

  • Leveling Merge Policy:

    • 每个level仅有1个组件,L0和L1合并,合并到L1中;
    • 由于组件较少,查询性能较高,LevelDB和RocksDB使用该策略;
  • Tiering Merge Policy:

    • 每个Level有N个组件,合并后生成Level+1的一个新组件;
    • 由于可以降低合并的频率,写入性能较高;

LSM-Tree 概念解析_第3张图片

LSM-Tree中写入数据

LSM-Tree中写入操作很快,在WAL中顺序写入操作内容,成功后,再写入MemTable即可。

LSM-Tree中更新数据

严格来讲,LSM-Tree中不存在更新操作,更新数据==写入一个新的k-v数据。
在读取的时候,从L0的SSTable开始查找,低层的SSTable必然比高层的SSTable数据更新,故总能读到最新的值。
整个LSM-Tree中可能存在多个key相同的数据,在合并SSTable的时候,会将旧值删除。

LSM-Tree中删除数据

删除操作仅记录key的删除操作标记,并不立即从文件中删除;当合并SSTable时,才真正的将数据删除。

LSM-Tree中读取数据

LSM-Tree的读取效率并不高,查找过程:

  • 先查找内存Memtable和Immutable,找到即返回;
  • 然后分别查找磁盘L0 SSTable->L1 SSTable->...,找到即返回;

LSM-Tree 概念解析_第4张图片

LSM-Tree优化读取

从查找过程可以看出,LSM-Tree的读取速度要比其他结构慢,需要使用一些索引技巧进行优化,比如在文件中增加索引块加快查询、使用布隆过滤器。

LevelDB Manifest文件

manifest文件记录所有的SSTable信息,比如Level、最小key、最大key等,可以用于快读定位目标SSTable。

SSTable的索引块

每个SSTable文件中加入索引块,索引块中记录key及其offset,key按顺序排列。
查找时,先在索引中二分查找key和offset,然后再到SSTable中读取key-value。

SSTable的布隆过滤器

对SSTable指定布隆过滤器,判定一个SSTable是否包含特定的建,以减少访问磁盘次数。

参考:

1.https://czqcgdma8j.feishu.cn/...
2.http://blog.fatedier.com/2016...

你可能感兴趣的:(LSM)